Ubiquitous/RT_Thread/:add rw007 driver and ov2640 driver

This commit is contained in:
chunyexixiaoyu 2021-06-21 17:17:16 +08:00
parent 4510a95e90
commit fedd6affc9
25 changed files with 4149 additions and 35 deletions

3
.gitignore vendored
View File

@ -1 +1,2 @@
.vscode
*.vscode
*.o

View File

@ -368,22 +368,20 @@ CONFIG_BSP_UART1_RXD_PIN=21
# CONFIG_BSP_USING_UART2 is not set
# CONFIG_BSP_USING_UART3 is not set
# CONFIG_BSP_USING_I2C1 is not set
# CONFIG_BSP_USING_SPI1 is not set
CONFIG_BSP_USING_SPI1=y
# CONFIG_BSP_USING_SPI1_AS_QSPI is not set
CONFIG_BSP_SPI1_CLK_PIN=27
CONFIG_BSP_SPI1_D0_PIN=28
CONFIG_BSP_SPI1_D1_PIN=26
CONFIG_BSP_SPI1_USING_SS0=y
CONFIG_BSP_SPI1_SS0_PIN=29
CONFIG_BSP_SPI1_USING_SS1=y
CONFIG_BSP_SPI1_SS1_PIN=8
# CONFIG_BSP_SPI1_USING_SS2 is not set
# CONFIG_BSP_SPI1_USING_SS3 is not set
# CONFIG_BSP_USING_LCD is not set
# CONFIG_BSP_USING_SDCARD is not set
CONFIG_BSP_USING_DVP=y
#
# The default pin assignment is based on the Maix Duino K210 development board
#
CONFIG_BSP_DVP_SCCB_SDA_PIN=40
CONFIG_BSP_DVP_SCCB_SCLK_PIN=41
CONFIG_BSP_DVP_CMOS_RST_PIN=42
CONFIG_BSP_DVP_CMOS_VSYNC_PIN=43
CONFIG_BSP_DVP_CMOS_PWDN_PIN=44
CONFIG_BSP_DVP_CMOS_XCLK_PIN=46
CONFIG_BSP_DVP_CMOS_PCLK_PIN=47
CONFIG_BSP_DVP_CMOS_HREF_PIN=45
CONFIG_BSP_USING_SDCARD=y
# CONFIG_BSP_USING_DVP is not set
#
# Kendryte SDK Config
@ -393,4 +391,14 @@ CONFIG_PKG_KENDRYTE_SDK_VERNUM=0x0055
#
# More Drivers
#
# CONFIG_PKG_USING_RW007 is not set
# CONFIG_DRV_USING_OV2640 is not set
#
# Applications
#
#
# Framework
#
CONFIG___STACKSIZE__=4096

View File

@ -0,0 +1,106 @@
#include <rtthread.h>
#include <rtdevice.h>
#include "stdio.h"
#include "string.h"
#include "dvp.h"
#include "fpioa.h"
#include "plic.h"
#include "sysctl.h"
#if(defined DRV_USING_OV2640 && defined BSP_USING_LCD)
#include<drv_ov2640.h>
#define RGB_BUF_SIZE (320*240*2)
#ifdef RT_USING_POSIX
#include <pthread.h>
#include <unistd.h>
#include <stdio.h>
#include <dfs_poll.h>
#ifdef RT_USING_POSIX_TERMIOS
#include <posix_termios.h>
#endif
#endif
static int g_fd = 0;
static _ioctl_shoot_para shoot_para_t = {0};
void ov2640_test(int argc, char **argv)
{
extern void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t *ptr);
g_fd = open("/dev/ov2640",O_RDONLY);
if(g_fd < 0)
{
printf("open ov2640 fail !!");
return;
}
if (argc < 2)
{
printf("Usage:ov2640 display images in real time or take photos \n");
printf("Like: ov2640_test 1(take photos )\n");
printf("Like: ov2640_test 0(display images in real time )\n");
close(g_fd);
return ;
}
uint32_t* rgbbuffer = rt_malloc(RGB_BUF_SIZE);
rt_thread_t tid;
rt_err_t ret = 0;
int temf = 0;
if(NULL == rgbbuffer)
{
printf("malloc rgbbuffer failed ! \n");
close(g_fd);
return;
}
temf = strtoul(argv[1],0, 10);
printf("ov2640_test choose %d mode \n",temf);
shoot_para_t.pdata = (uint32_t)(rgbbuffer);
shoot_para_t.length = RGB_BUF_SIZE;
if(temf == 0)
{
void lcd_show_ov2640_thread(uint32_t* rgbbuffer);
tid = rt_thread_create("lcdshow", lcd_show_ov2640_thread, rgbbuffer,3000, 9, 20);
rt_thread_startup(tid);
}
else
{
memset(rgbbuffer,0,320*240*2);
ret = ioctl(g_fd,IOCTRL_CAMERA_START_SHOT,&shoot_para_t);
// ret = rt_ov2640_start_shoot((uint32_t)(rgbbuffer), RGB_BUF_SIZE);
if(RT_ERROR == ret)
{
printf("ov2640 can't wait event flag");
close(g_fd);
return;
}
lcd_draw_picture(0, 0, 320, 240, rgbbuffer);
rt_thread_mdelay(100);
printf("the lcd has shown the image \n");
rt_free(rgbbuffer);
close(g_fd);
}
}
MSH_CMD_EXPORT(ov2640_test,lcd show camera shot image);
void lcd_show_ov2640_thread(uint32_t* rgbbuffer)
{
extern void lcd_draw_picture(uint16_t x1, uint16_t y1, uint16_t width, uint16_t height, uint32_t *ptr);
rt_err_t ret = 0;
while(1)
{
ret = ioctl(g_fd,IOCTRL_CAMERA_START_SHOT,&shoot_para_t);
if(RT_ERROR == ret)
{
printf("ov2640 can't wait event flag");
rt_free(rgbbuffer);
return;
}
lcd_draw_picture(0, 0, 320, 240, rgbbuffer);
rt_thread_mdelay(2);
}
}
#endif

View File

@ -0,0 +1,105 @@
#include <rtthread.h>
#ifdef PKG_USING_RW007
#include <netdb.h>
#include <string.h>
#include <finsh.h>
#include <sys/socket.h>
static const char send_data[] = "This is TCP Client from AIIT";
void rw007_test(int argc, char **argv)
{
int ret;
char *recv_data;
struct hostent *host;
int sock, bytes_received;
struct sockaddr_in server_addr;
const char *url;
int port;
extern rt_bool_t rt_wlan_is_connected(void);
if (rt_wlan_is_connected() != 1)
{
printf("Please connect a wifi firstly\n");
return;
}
if (argc < 3)
{
printf("Usage: rw007 URL PORT\n");
printf("Like: rw007 192.168.12.44 5000\n");
return ;
}
url = argv[1];
port = strtoul(argv[2], 0, 10);
host = gethostbyname(url);
recv_data = rt_malloc(1024);
if (recv_data == RT_NULL)
{
printf("No memory\n");
return;
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("Socket error\n");
rt_free(recv_data);
return;
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
{
printf("Connect fail!\n");
closesocket(sock);
rt_free(recv_data);
return;
}
else
{
printf("Connect successful\n");
}
while (1)
{
bytes_received = recv(sock, recv_data, 1024 - 1, 0);
if (bytes_received < 0)
{
closesocket(sock);
printf("\nreceived error,close the socket.\r\n");
rt_free(recv_data);
break;
}
else if (bytes_received == 0)
{
closesocket(sock);
printf("\nreceived error,close the socket.\r\n");
rt_free(recv_data);
break;
}
recv_data[bytes_received] = '\0';
if (strncmp(recv_data, "q", 1) == 0 || strncmp(recv_data, "Q", 1) == 0)
{
closesocket(sock);
printf("\n got a 'q' or 'Q',close the socket.\r\n");
rt_free(recv_data);
break;
}
else
{
printf("\nReceived data = %s ", recv_data);
}
ret = send(sock, send_data, strlen(send_data), 0);
if (ret < 0)
{
closesocket(sock);
printf("\nsend error,close the socket.\r\n");
rt_free(recv_data);
break;
}
else if (ret == 0)
{
printf("\n Send warning,send function return 0.\r\n");
}
}
return;
}
MSH_CMD_EXPORT(rw007_test, a tcp client sample);
#endif

View File

@ -246,18 +246,15 @@
#define BSP_USING_UART1
#define BSP_UART1_TXD_PIN 20
#define BSP_UART1_RXD_PIN 21
#define BSP_USING_DVP
/* The default pin assignment is based on the Maix Duino K210 development board */
#define BSP_DVP_SCCB_SDA_PIN 40
#define BSP_DVP_SCCB_SCLK_PIN 41
#define BSP_DVP_CMOS_RST_PIN 42
#define BSP_DVP_CMOS_VSYNC_PIN 43
#define BSP_DVP_CMOS_PWDN_PIN 44
#define BSP_DVP_CMOS_XCLK_PIN 46
#define BSP_DVP_CMOS_PCLK_PIN 47
#define BSP_DVP_CMOS_HREF_PIN 45
#define BSP_USING_SPI1
#define BSP_SPI1_CLK_PIN 27
#define BSP_SPI1_D0_PIN 28
#define BSP_SPI1_D1_PIN 26
#define BSP_SPI1_USING_SS0
#define BSP_SPI1_SS0_PIN 29
#define BSP_SPI1_USING_SS1
#define BSP_SPI1_SS1_PIN 8
#define BSP_USING_SDCARD
/* Kendryte SDK Config */
@ -265,6 +262,11 @@
/* More Drivers */
/* Applications */
/* Framework */
#define __STACKSIZE__ 4096
#endif

View File

@ -126,7 +126,28 @@ CONFIG_DFS_FILESYSTEMS_MAX=2
CONFIG_DFS_FILESYSTEM_TYPES_MAX=2
CONFIG_DFS_FD_MAX=16
# CONFIG_RT_USING_DFS_MNTTABLE is not set
# CONFIG_RT_USING_DFS_ELMFAT is not set
CONFIG_RT_USING_DFS_ELMFAT=y
#
# elm-chan's FatFs, Generic FAT Filesystem Module
#
CONFIG_RT_DFS_ELM_CODE_PAGE=437
CONFIG_RT_DFS_ELM_WORD_ACCESS=y
# CONFIG_RT_DFS_ELM_USE_LFN_0 is not set
# CONFIG_RT_DFS_ELM_USE_LFN_1 is not set
# CONFIG_RT_DFS_ELM_USE_LFN_2 is not set
CONFIG_RT_DFS_ELM_USE_LFN_3=y
CONFIG_RT_DFS_ELM_USE_LFN=3
CONFIG_RT_DFS_ELM_LFN_UNICODE_0=y
# CONFIG_RT_DFS_ELM_LFN_UNICODE_1 is not set
# CONFIG_RT_DFS_ELM_LFN_UNICODE_2 is not set
# CONFIG_RT_DFS_ELM_LFN_UNICODE_3 is not set
CONFIG_RT_DFS_ELM_LFN_UNICODE=0
CONFIG_RT_DFS_ELM_MAX_LFN=255
CONFIG_RT_DFS_ELM_DRIVES=2
CONFIG_RT_DFS_ELM_MAX_SECTOR_SIZE=512
# CONFIG_RT_DFS_ELM_USE_ERASE is not set
CONFIG_RT_DFS_ELM_REENTRANT=y
CONFIG_RT_USING_DFS_DEVFS=y
# CONFIG_RT_USING_DFS_ROMFS is not set
# CONFIG_RT_USING_DFS_RAMFS is not set
@ -162,7 +183,7 @@ CONFIG_RT_USING_PIN=y
# CONFIG_RT_USING_SDIO is not set
CONFIG_RT_USING_SPI=y
# CONFIG_RT_USING_QSPI is not set
# CONFIG_RT_USING_SPI_MSD is not set
CONFIG_RT_USING_SPI_MSD=y
# CONFIG_RT_USING_SFUD is not set
# CONFIG_RT_USING_ENC28J60 is not set
# CONFIG_RT_USING_SPI_WIFI is not set
@ -348,10 +369,12 @@ CONFIG_BSP_USING_USB_TO_USART=y
CONFIG_BSP_USING_SRAM=y
# CONFIG_BSP_USING_SPI_FLASH is not set
# CONFIG_BSP_USING_EEPROM is not set
# CONFIG_BSP_USING_OV2640 is not set
CONFIG_BSP_USING_OV2640=y
# CONFIG_BSP_USING_ETH is not set
# CONFIG_BSP_USING_MPU6050 is not set
# CONFIG_BSP_USING_SDCARD is not set
CONFIG_BSP_USING_SDCARD=y
CONFIG_SDCARD_SPI2_CS_PIN=28
CONFIG_SDCARD_SPI_BUS_NAME="spi2"
#
# On-chip Peripheral Drivers
@ -373,7 +396,9 @@ CONFIG_BSP_USING_SPI=y
CONFIG_BSP_USING_SPI1=y
# CONFIG_BSP_SPI1_TX_USING_DMA is not set
# CONFIG_BSP_SPI1_RX_USING_DMA is not set
# CONFIG_BSP_USING_SPI2 is not set
CONFIG_BSP_USING_SPI2=y
# CONFIG_BSP_SPI2_TX_USING_DMA is not set
# CONFIG_BSP_SPI2_RX_USING_DMA is not set
# CONFIG_BSP_USING_ADC is not set
CONFIG_BSP_USING_I2C1=y
CONFIG_BSP_I2C1_SCL_PIN=54
@ -397,3 +422,15 @@ CONFIG_BSP_USING_FMC=y
#
# More Drivers
#
# CONFIG_PKG_USING_RW007 is not set
# CONFIG_RW007_NOT_USE_EXAMPLE_DRIVERS is not set
# CONFIG_RW007_USING_STM32_DRIVERS is not set
# CONFIG_DRV_USING_OV2640 is not set
#
# Applications
#
#
# Framework
#

View File

@ -0,0 +1,97 @@
#include <rtthread.h>
#include <rtdevice.h>
#include "stdio.h"
#include "string.h"
#ifdef DRV_USING_OV2640
#ifdef RT_USING_POSIX
#include <dfs_posix.h>
#include <dfs_poll.h>
#ifdef RT_USING_POSIX_TERMIOS
#include <posix_termios.h>
#endif
#endif
#include<drv_ov2640.h>
#define JPEG_BUF_SIZE (1024*200)
#define UART_NUMBER2 "uart2"
void ov2640_test(int argc, char **argv)
{
rt_err_t ret = 0;
int fd = 0;
fd = open("/dev/ov2640",O_RDONLY);
if(fd < 0)
{
printf("open ov2640 fail !!");
return;
}
rt_uint8_t* JpegBuffer = rt_malloc(JPEG_BUF_SIZE);
_ioctl_shoot_para shoot_para_t = {0};
if (RT_NULL == JpegBuffer)
{
printf("JpegBuffer senddata buf malloc error!\n");
return;
}
printf("ov2640 test by printing the image value in memory \r\n");
shoot_para_t.pdata = (uint32_t)JpegBuffer;
shoot_para_t.length = JPEG_BUF_SIZE;
ret = ioctl(fd,IOCTRL_CAMERA_START_SHOT,&shoot_para_t);
if(RT_ERROR == ret)
{
printf("ov2640 can't wait event flag");
return;
}
printf("print the vaule:\r\n\r\n");
ret = rt_ov2640_calculate_jpeg_len(JpegBuffer,JPEG_BUF_SIZE);
printf("photo leghth is %d :\r\n\r\n",ret);
#ifdef BSP_USING_UART2
void img_output_uart2(rt_uint8_t* jpegbuf,rt_uint16_t len);
img_output_uart2(JpegBuffer,ret);
#endif
for(int i =0;i<ret;i++)
{
printf("%x",*(JpegBuffer+i));
}
printf("\r\n\r\n above :\r\n\r\n");
rt_free(JpegBuffer);
close(fd);
return;
}
MSH_CMD_EXPORT(ov2640_test,printing the image value in memory);
#ifdef BSP_USING_UART2
void img_output_uart2(rt_uint8_t* jpegbuf,rt_uint16_t len)
{
static rt_uint8_t i =0;
static rt_device_t serial = NULL;
int ret = RT_EOK;
if(i == 0)
{
i = 1;
serial = rt_device_find(UART_NUMBER2);
if (!serial)
{
printf("find uart2 failed!\n");
i = 2;
return;
}
ret = rt_device_open(serial, RT_DEVICE_OFLAG_RDWR | RT_DEVICE_FLAG_INT_RX);
if(ret != RT_EOK)
{
printf("open uart2 failed!\n");
i = 2;
return ;
}
}
if(i == 1)
{
rt_device_write(serial, 0, jpegbuf, len);
}
}
#endif
#endif

View File

@ -0,0 +1,106 @@
#include <rtthread.h>
#ifdef PKG_USING_RW007
#include <netdb.h>
#include <string.h>
#include <finsh.h>
#include <sys/socket.h>
static const char send_data[] = "This is TCP Client from AIIT";
void rw007_test(int argc, char **argv)
{
int ret;
char *recv_data;
struct hostent *host;
int sock, bytes_received;
struct sockaddr_in server_addr;
const char *url;
int port;
extern rt_bool_t rt_wlan_is_connected(void);
if (rt_wlan_is_connected() != 1)
{
printf("Please connect a wifi firstly\n");
return;
}
if (argc < 3)
{
printf("Usage: tcpclient URL PORT\n");
printf("Like: tcpclient 192.168.12.44 5000\n");
return ;
}
url = argv[1];
port = strtoul(argv[2], 0, 10);
host = gethostbyname(url);
recv_data = rt_malloc(1024);
if (recv_data == RT_NULL)
{
printf("No memory\n");
return;
}
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) == -1)
{
printf("Socket error\n");
rt_free(recv_data);
return;
}
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(port);
server_addr.sin_addr = *((struct in_addr *)host->h_addr);
rt_memset(&(server_addr.sin_zero), 0, sizeof(server_addr.sin_zero));
if (connect(sock, (struct sockaddr *)&server_addr, sizeof(struct sockaddr)) == -1)
{
printf("Connect fail!\n");
closesocket(sock);
rt_free(recv_data);
return;
}
else
{
printf("Connect successful\n");
}
while (1)
{
bytes_received = recv(sock, recv_data, 1024 - 1, 0);
if (bytes_received < 0)
{
closesocket(sock);
printf("\nreceived error,close the socket.\r\n");
rt_free(recv_data);
break;
}
else if (bytes_received == 0)
{
closesocket(sock);
printf("\nreceived error,close the socket.\r\n");
rt_free(recv_data);
break;
}
recv_data[bytes_received] = '\0';
if (strncmp(recv_data, "q", 1) == 0 || strncmp(recv_data, "Q", 1) == 0)
{
closesocket(sock);
printf("\n got a 'q' or 'Q',close the socket.\r\n");
rt_free(recv_data);
break;
}
else
{
printf("\nReceived data = %s ", recv_data);
}
ret = send(sock, send_data, strlen(send_data), 0);
if (ret < 0)
{
closesocket(sock);
printf("\nsend error,close the socket.\r\n");
rt_free(recv_data);
break;
}
else if (ret == 0)
{
printf("\n Send warning,send function return 0.\r\n");
}
}
return;
}
MSH_CMD_EXPORT(rw007_test, a tcp client sample);
#endif

View File

@ -91,6 +91,20 @@
#define DFS_FILESYSTEMS_MAX 2
#define DFS_FILESYSTEM_TYPES_MAX 2
#define DFS_FD_MAX 16
#define RT_USING_DFS_ELMFAT
/* elm-chan's FatFs, Generic FAT Filesystem Module */
#define RT_DFS_ELM_CODE_PAGE 437
#define RT_DFS_ELM_WORD_ACCESS
#define RT_DFS_ELM_USE_LFN_3
#define RT_DFS_ELM_USE_LFN 3
#define RT_DFS_ELM_LFN_UNICODE_0
#define RT_DFS_ELM_LFN_UNICODE 0
#define RT_DFS_ELM_MAX_LFN 255
#define RT_DFS_ELM_DRIVES 2
#define RT_DFS_ELM_MAX_SECTOR_SIZE 512
#define RT_DFS_ELM_REENTRANT
#define RT_USING_DFS_DEVFS
/* Device Drivers */
@ -107,6 +121,7 @@
#define RT_USING_I2C_BITOPS
#define RT_USING_PIN
#define RT_USING_SPI
#define RT_USING_SPI_MSD
#define RT_USING_WIFI
#define RT_WLAN_DEVICE_STA_NAME "wlan0"
#define RT_WLAN_DEVICE_AP_NAME "wlan1"
@ -230,6 +245,10 @@
#define BSP_USING_USB_TO_USART
#define BSP_USING_SRAM
#define BSP_USING_OV2640
#define BSP_USING_SDCARD
#define SDCARD_SPI2_CS_PIN 28
#define SDCARD_SPI_BUS_NAME "spi2"
/* On-chip Peripheral Drivers */
@ -238,6 +257,7 @@
#define BSP_USING_UART1
#define BSP_USING_SPI
#define BSP_USING_SPI1
#define BSP_USING_SPI2
#define BSP_USING_I2C1
#define BSP_I2C1_SCL_PIN 54
#define BSP_I2C1_SDA_PIN 55
@ -250,4 +270,9 @@
/* More Drivers */
/* Applications */
/* Framework */
#endif

View File

@ -1,5 +1,5 @@
menu "More Drivers"
#source "$RT_Thread_DIR/drivers/rw007/Kconfig"
#source "$RT_Thread_DIR/drivers/ov2640/Kconfig"
source "$RT_Thread_DIR/drivers/rw007/Kconfig"
source "$RT_Thread_DIR/drivers/ov2640/Kconfig"
endmenu

View File

@ -0,0 +1,14 @@
menuconfig DRV_USING_OV2640
bool "ov2640 driver"
default n
if SOC_FAMILY_STM32
config DRV_USING_OV2640
select BSP_USING_DCMI
endif
if BOARD_K210_EVB
config DRV_USING_OV2640
select BSP_USING_DVP
endif

View File

@ -0,0 +1,7 @@
Import('RTT_ROOT')
from building import *
cwd = GetCurrentDir()
objs = SConscript(os.path.join(cwd, 'ov2640_source', 'SConscript'))
Return('objs')

View File

@ -0,0 +1,14 @@
import os
from building import *
Import('RTT_ROOT')
Import('rtconfig')
cwd = GetCurrentDir()
DEPENDS = ["DRV_USING_OV2640"]
SOURCES = []
if GetDepend(['DRV_USING_OV2640']):
SOURCES += ['drv_ov2640.c']
path = [cwd]
objs = DefineGroup('ov2640', src = SOURCES, depend = DEPENDS,CPPPATH = path)
Return("objs")

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,168 @@
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2020-07-27 thread-liu first version
* 2021-1-15 xiaoyu add set resolution function and the way of reset different manufactures's ov2640 egg:zhendianyuanzi and weixue
*/
#ifndef __DRV_OV2640_H__
#define __DRV_OV2640_H__
#include <rtthread.h>
#ifdef __cplusplus
extern "C" {
#endif
#ifdef SOC_FAMILY_STM32
#include<drv_dcmi.h>
#elif defined BOARD_K210_EVB
#include<drv_dvp.h>
#endif
#ifdef SOC_FAMILY_STM32
#define DEV_ADDRESS 0x30 /* OV2640 address with rt-thread iic */
#elif defined BOARD_K210_EVB
#define DEV_ADDRESS 0x60 /* OV2640 address */
#endif
#define LARGE_PHOTO_MODE (8)
#define I2C_NAME "i2c1"
#define RECV_EVENT_FLAG (1 << 1) //flag about event control block
#define OV2640_MID 0X7FA2
#define OV2640_PID 0X2642
#define OV2640_ZDYZ //The macro definition of the manufacturer's product
//DSP register address map table for OV2640 when DSP address (0xFF =0X00) is selected
#define OV2640_DSP_R_BYPASS 0x05
#define OV2640_DSP_Qs 0x44
#define OV2640_DSP_CTRL 0x50
#define OV2640_DSP_HSIZE1 0x51
#define OV2640_DSP_VSIZE1 0x52
#define OV2640_DSP_XOFFL 0x53
#define OV2640_DSP_YOFFL 0x54
#define OV2640_DSP_VHYX 0x55
#define OV2640_DSP_DPRP 0x56
#define OV2640_DSP_TEST 0x57
#define OV2640_DSP_ZMOW 0x5A
#define OV2640_DSP_ZMOH 0x5B
#define OV2640_DSP_ZMHH 0x5C
#define OV2640_DSP_BPADDR 0x7C
#define OV2640_DSP_BPDATA 0x7D
#define OV2640_DSP_CTRL2 0x86
#define OV2640_DSP_CTRL3 0x87
#define OV2640_DSP_SIZEL 0x8C
#define OV2640_DSP_HSIZE2 0xC0
#define OV2640_DSP_VSIZE2 0xC1
#define OV2640_DSP_CTRL0 0xC2
#define OV2640_DSP_CTRL1 0xC3
#define OV2640_DSP_R_DVP_SP 0xD3
#define OV2640_DSP_IMAGE_MODE 0xDA
#define OV2640_DSP_RESET 0xE0
#define OV2640_DSP_MS_SP 0xF0
#define OV2640_DSP_SS_ID 0x7F
#define OV2640_DSP_SS_CTRL 0xF8
#define OV2640_DSP_MC_BIST 0xF9
#define OV2640_DSP_MC_AL 0xFA
#define OV2640_DSP_MC_AH 0xFB
#define OV2640_DSP_MC_D 0xFC
#define OV2640_DSP_P_STATUS 0xFE
#define OV2640_DSP_RA_DLMT 0xFF
//DSP register address map table for OV2640 when DSP address (0xFF =0X01) is selected
#define OV2640_SENSOR_GAIN 0x00
#define OV2640_SENSOR_COM1 0x03
#define OV2640_SENSOR_REG04 0x04
#define OV2640_SENSOR_REG08 0x08
#define OV2640_SENSOR_COM2 0x09
#define OV2640_SENSOR_PIDH 0x0A
#define OV2640_SENSOR_PIDL 0x0B
#define OV2640_SENSOR_COM3 0x0C
#define OV2640_SENSOR_COM4 0x0D
#define OV2640_SENSOR_AEC 0x10
#define OV2640_SENSOR_CLKRC 0x11
#define OV2640_SENSOR_COM7 0x12
#define OV2640_SENSOR_COM8 0x13
#define OV2640_SENSOR_COM9 0x14
#define OV2640_SENSOR_COM10 0x15
#define OV2640_SENSOR_HREFST 0x17
#define OV2640_SENSOR_HREFEND 0x18
#define OV2640_SENSOR_VSTART 0x19
#define OV2640_SENSOR_VEND 0x1A
#define OV2640_SENSOR_MIDH 0x1C
#define OV2640_SENSOR_MIDL 0x1D
#define OV2640_SENSOR_AEW 0x24
#define OV2640_SENSOR_AEB 0x25
#define OV2640_SENSOR_W 0x26
#define OV2640_SENSOR_REG2A 0x2A
#define OV2640_SENSOR_FRARL 0x2B
#define OV2640_SENSOR_ADDVSL 0x2D
#define OV2640_SENSOR_ADDVHS 0x2E
#define OV2640_SENSOR_YAVG 0x2F
#define OV2640_SENSOR_REG32 0x32
#define OV2640_SENSOR_ARCOM2 0x34
#define OV2640_SENSOR_REG45 0x45
#define OV2640_SENSOR_FLL 0x46
#define OV2640_SENSOR_FLH 0x47
#define OV2640_SENSOR_COM19 0x48
#define OV2640_SENSOR_ZOOMS 0x49
#define OV2640_SENSOR_COM22 0x4B
#define OV2640_SENSOR_COM25 0x4E
#define OV2640_SENSOR_BD50 0x4F
#define OV2640_SENSOR_BD60 0x50
#define OV2640_SENSOR_REG5D 0x5D
#define OV2640_SENSOR_REG5E 0x5E
#define OV2640_SENSOR_REG5F 0x5F
#define OV2640_SENSOR_REG60 0x60
#define OV2640_SENSOR_HISTO_LOW 0x61
#define OV2640_SENSOR_HISTO_HIGH 0x62
#define IOCTRL_CAMERA_START_SHOT (22) // start shoot
#define IOCTRL_CAMERA_SET_RESO (23) //set resolution
#define IOCTRL_CAMERA_SET_LIGHT (24) //set light mode
#define IOCTRL_CAMERA_SET_COLOR (25) //set color saturation
#define IOCTRL_CAMERA_SET_BRIGHTNESS (26) //set color brightness
#define IOCTRL_CAMERA_SET_CONTRAST (27) //set contrast
#define IOCTRL_CAMERA_SET_EFFECT (28) //set effect
#define IOCTRL_CAMERA_SET_EXPOSURE (29) //set auto exposure
struct camera_device
{
struct rt_device parent; /**< RT-Thread device struct */
};
typedef struct
{
uint32_t pdata;
uint32_t length;
}_ioctl_shoot_para;
extern rt_uint32_t rt_ov2640_calculate_jpeg_len(rt_uint8_t* pdata,rt_uint32_t maxlength);
extern rt_err_t rt_ov2640_start_shoot(uint32_t pdata, uint32_t length);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,59 @@
menuconfig PKG_USING_RW007
bool "rw007: SPI WIFI rw007 driver"
select RT_USING_SPI
select RT_USING_PIN
select RT_USING_LWIP
default n
help
if "PKG_USING_RW007" is opened, "RT_USING_LWIP" will be default selected.
if PKG_USING_RW007
choice
prompt "example driver port"
default RW007_USING_STM32_DRIVERS
config RW007_NOT_USE_EXAMPLE_DRIVERS
bool "not use example driver, porting by myself"
config RW007_USING_STM32_DRIVERS
bool "rw007 for stm32"
# config RW007_USING_IMXRT_DRIVERS
# bool "rw007 for imxrt"
endchoice
config RW007_SPI_MAX_HZ
int "SPI Max Hz"
default 30000000
if !RW007_NOT_USE_EXAMPLE_DRIVERS
if RW007_USING_STM32_DRIVERS || RW007_USING_IMXRT_DRIVERS
config RW007_SPI_BUS_NAME
string "RW007 BUS NAME"
default "spi1"
config RW007_CS_PIN
int "CS pin index"
default 86
endif
config RW007_BOOT0_PIN
int "BOOT0 pin index (same as spi clk pin)"
default 19
config RW007_BOOT1_PIN
int "BOOT1 pin index (same as spi cs pin)"
default 86
config RW007_INT_BUSY_PIN
int "INT/BUSY pin index"
default 87
config RW007_RST_PIN
int "RESET pin index"
default 88
endif
endif

View File

@ -0,0 +1,7 @@
Import('RTT_ROOT')
from building import *
cwd = GetCurrentDir()
objs = SConscript(os.path.join(cwd, 'rw007-source', 'SConscript'))
Return('objs')

View File

@ -0,0 +1,52 @@
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf

View File

@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@ -0,0 +1,59 @@
# rw007
[中文页](README_ZH.md) | English
## 1. Introduction
**RW007** is a SPI/UART high-speed wifi module based on Cortex-M4 WIFI SOC developed by Shanghai Ruiside Electronic Technology Co., Ltd. The warehouse is the SPI driver of **rw007**
**RW007** The hardware design is simple. In SPI mode, users only need to reserve 1 set of SPI signals, one interrupt input, and one IO output, including a total of 8 pins for power and ground.
### 1.1. File structure
| Folder | Description |
| ---- | ---- |
| src | Core driver source code, which mainly implements communication logic |
| inc | Header file directory |
| example | Platform porting example |
### 1.2 License
The at_device package complies with the Apache 2.0 license, see the `LICENSE` file for details.
### 1.3 Dependency
- RT-Thread 3.0+
- RT-Thread LWIP component
- RT-Thread SPI driver framework
- RT-Thread PIN driver framework (sample platform code dependency)
### 1.4 Configuration Macro Description
The relevant configuration macros will be configured in env during automatic configuration. The manual configuration is as follows
Type description
- bool: definition is valid, undefined, not valid
- string: string
- int: number
|Macro|Type|Function|
|--|--|--|
|PKG_USING_RW007|bool|Enable rw007 driver, use this software package, you need to define this macro|
|RW007_USING_STM32_DRIVERS|bool|Enable STM32 platform migration example|
|RW007_USING_IMXRT_DRIVERS|bool|Enable IMXRT platform migration example|
|RW007_SPI_BUS_NAME|string|The SPI bus device name used in example|
|RW007_CS_PIN|int|The serial number of the SPI chip select pin used in the example in the pin driver|
|RW007_BOOT0_PIN|int|The serial number of the BOOT0 pin used in the example in the pin driver (the same pin is multiplexed with the CLK of SPI)|
|RW007_BOOT1_PIN|int|The serial number of the BOOT1 pin used in the example in the pin driver (the same pin is multiplexed with the CS of SPI)|
|RW007_INT_BUSY_PIN|int|The serial number of the INT/BUSY pin used in the example in the pin driver|
|RW007_RST_PIN|int|The serial number of the RST pin used in the example in the pin driver|
## 2. Matters needing attention
Because of the pin multiplexing situation, the driver of the bsp SPI needs to be configured during Config.
## 4. Contact
- Maintenance: RT-Thread development team
- Homepage: https://github.com/RT-Thread-packages/rw007

View File

@ -0,0 +1,59 @@
# rw007
中文页 | [English](README.md)
## 1. 简介
**RW007**是由上海睿赛德电子科技有限公司开发基于Cortex-M4 WIFI SOC的SPI/UART 高速wifi模块。该仓库为**rw007**的SPI驱动
**RW007**硬件设计简单SPI模式下用户只需要预留1组SPI信号一个中断输入一个IO输出即可包含电源和地总共8个引脚。
### 1.1. 文件结构
| 文件夹 | 说明 |
| ---- | ---- |
| src | 核心驱动源码,主要实现通信逻辑 |
| inc | 头文件目录 |
| example | 平台移植示例 |
### 1.2 许可证
at_device package 遵循 Apache 2.0 许可,详见 `LICENSE` 文件。
### 1.3 依赖
- RT-Thread 3.0+
- RT-Thread LWIP 组件
- RT-Thread SPI 驱动框架
- RT-Thread PIN 驱动框架(示例平台代码依赖)
### 1.4 配置宏说明
自动配置时相关配置宏将在env中被配置 手动配置参考如下
类型说明
- bool: 定义生效 未定义 不生效
- string: 字符串
- int: 数值
|宏|类型|功能|
|--|--|--|
|PKG_USING_RW007|bool|开启rw007驱动使用该软件包则需要定义该宏|
|RW007_USING_STM32_DRIVERS|bool|使能STM32平台移植示例|
|RW007_USING_IMXRT_DRIVERS|bool|使能IMXRT平台移植示例|
|RW007_SPI_BUS_NAME|string|example中使用的SPI总线设备名称|
|RW007_CS_PIN|int|example中使用的SPI 片选引脚在pin驱动中的序号|
|RW007_BOOT0_PIN|int|example中使用的BOOT0引脚在pin驱动中的序号(与SPI的CLK是同一引脚复用)|
|RW007_BOOT1_PIN|int|example中使用的BOOT1引脚在pin驱动中的序号(与SPI的CS是同一引脚复用)|
|RW007_INT_BUSY_PIN|int|example中使用的INT/BUSY引脚在pin驱动中的序号|
|RW007_RST_PIN|int|example中使用的RST引脚在pin驱动中的序号|
## 2. 注意事项
由于存在引脚复用情况所以bsp的SPI的驱动需要引脚配置在Config时进行。
## 4. 联系方式
- 维护RT-Thread 开发团队
- 主页https://github.com/RT-Thread-packages/rw007

View File

@ -0,0 +1,87 @@
#-*- encoding: utf-8 -*-
#---------------------------------------------------------------------------------
# @File: Sconscript for package
# @Author: liu2guang
# @Date: 2018-09-19 18:07:00(v0.1.0)
#
# @LICENSE: GPLv3: https://github.com/rtpkgs/buildpkg/blob/master/LICENSE.
#
#---------------------------------------------------------------------------------
import os
from building import *
Import('RTT_ROOT')
Import('rtconfig')
#---------------------------------------------------------------------------------
# Package configuration
#---------------------------------------------------------------------------------
PKGNAME = "rw007"
VERSION = "v0.0.1"
DEPENDS = ["PKG_USING_RW007"]
#---------------------------------------------------------------------------------
# Compile the configuration
#
# SOURCES: Need to compile c and c++ source, auto search when SOURCES is empty
#
# LOCAL_CPPPATH: Local file path (.h/.c/.cpp)
# LOCAL_CCFLAGS: Local compilation parameter
# LOCAL_ASFLAGS: Local assembly parameters
#
# CPPPATH: Global file path (.h/.c/.cpp), auto search when LOCAL_CPPPATH/CPPPATH
# is empty # no pass!!!
# CCFLAGS: Global compilation parameter
# ASFLAGS: Global assembly parameters
#
# CPPDEFINES: Global macro definition
# LOCAL_CPPDEFINES: Local macro definition
#
# LIBS: Specify the static library that need to be linked
# LIBPATH: Specify the search directory for the library file (.lib/.a)
#
# LINKFLAGS: Link options
#---------------------------------------------------------------------------------
SOURCES = ["src/spi_wifi_rw007.c"]
if GetDepend(['RW007_USING_STM32_DRIVERS']):
SOURCES += ["example/rw007_stm32_port.c"]
LOCAL_CPPPATH = []
LOCAL_CCFLAGS = ""
LOCAL_ASFLAGS = ""
CPPPATH = [GetCurrentDir(), os.path.join(GetCurrentDir(), 'inc')]
CCFLAGS = ""
ASFLAGS = ""
CPPDEFINES = []
LOCAL_CPPDEFINES = []
LIBS = []
LIBPATH = []
LINKFLAGS = ""
SOURCES_IGNORE = []
CPPPATH_IGNORE = []
#---------------------------------------------------------------------------------
# Main target
#---------------------------------------------------------------------------------
objs = DefineGroup(name = PKGNAME, src = SOURCES, depend = DEPENDS,
CPPPATH = CPPPATH,
CCFLAGS = CCFLAGS,
ASFLAGS = ASFLAGS,
LOCAL_CPPPATH = LOCAL_CPPPATH,
LOCAL_CCFLAGS = LOCAL_CCFLAGS,
LOCAL_ASFLAGS = LOCAL_ASFLAGS,
CPPDEFINES = CPPDEFINES,
LOCAL_CPPDEFINES = LOCAL_CPPDEFINES,
LIBS = LIBS,
LIBPATH = LIBPATH,
LINKFLAGS = LINKFLAGS)
Return("objs")
#---------------------------------------------------------------------------------
# End
#---------------------------------------------------------------------------------

View File

@ -0,0 +1,70 @@
#include <rtthread.h>
#ifdef RW007_USING_STM32_DRIVERS
#include <rtdevice.h>
#include <drv_spi.h>
#include <board.h>
#include <spi_wifi_rw007.h>
extern void spi_wifi_isr(int vector);
static void rw007_gpio_init(void)
{
/* Configure IO */
rt_pin_mode(RW007_RST_PIN, PIN_MODE_OUTPUT);
rt_pin_mode(RW007_INT_BUSY_PIN, PIN_MODE_INPUT_PULLDOWN);
/* Reset rw007 and config mode */
rt_pin_write(RW007_RST_PIN, PIN_LOW);
rt_thread_delay(rt_tick_from_millisecond(100));
rt_pin_write(RW007_RST_PIN, PIN_HIGH);
/* Wait rw007 ready(exit busy stat) */
while(!rt_pin_read(RW007_INT_BUSY_PIN))
{
rt_thread_delay(5);
}
rt_thread_delay(rt_tick_from_millisecond(200));
rt_pin_mode(RW007_INT_BUSY_PIN, PIN_MODE_INPUT_PULLUP);
}
int wifi_spi_device_init(void)
{
char sn_version[32];
GPIO_TypeDef *cs_gpiox;
uint16_t cs_pin;
cs_gpiox = (GPIO_TypeDef *)((rt_base_t)GPIOA + (rt_base_t)(RW007_CS_PIN / 16) * 0x0400UL);
cs_pin = (uint16_t)(1 << RW007_CS_PIN % 16);
rw007_gpio_init();
rt_hw_spi_device_attach(RW007_SPI_BUS_NAME, "wspi", cs_gpiox, cs_pin);
rt_hw_wifi_init("wspi");
rt_wlan_set_mode(RT_WLAN_DEVICE_STA_NAME, RT_WLAN_STATION);
rt_wlan_set_mode(RT_WLAN_DEVICE_AP_NAME, RT_WLAN_AP);
rw007_sn_get(sn_version);
rt_kprintf("\nrw007 sn: [%s]\n", sn_version);
rw007_version_get(sn_version);
rt_kprintf("rw007 ver: [%s]\n\n", sn_version);
return 0;
}
INIT_APP_EXPORT(wifi_spi_device_init);
static void int_wifi_irq(void * p)
{
((void)p);
spi_wifi_isr(0);
}
void spi_wifi_hw_init(void)
{
rt_pin_attach_irq(RW007_INT_BUSY_PIN, PIN_IRQ_MODE_FALLING, int_wifi_irq, 0);
rt_pin_irq_enable(RW007_INT_BUSY_PIN, RT_TRUE);
}
#endif /* RW007_USING_STM32_DRIVERS */

View File

@ -0,0 +1,221 @@
/*
* COPYRIGHT (C) 2018, Real-Thread Information Technology Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2014-07-31 aozima the first version
* 2014-09-18 aozima update command & response.
*/
#ifndef SPI_WIFI_H_INCLUDED
#define SPI_WIFI_H_INCLUDED
#include <stdint.h>
#include <rtdevice.h>
typedef enum
{
master_cmd_phase = 0x01,
master_data_phase,
slave_cmd_phase,
slave_data_phase,
}phase_type;
typedef enum
{
TRANSFER_DATA_SUCCESS = 0x00,
TRANSFER_DATA_ERROR,
TRANSFER_DATA_CONTINUE,
}rw007_transfer_state;
/* little-endian */
struct spi_master_request
{
uint8_t reserve1;
uint8_t flag: 4;
uint8_t type: 4;
uint16_t reserve2;
uint16_t seq;
uint16_t M2S_len; // master to slave data len.
uint32_t magic1;
uint32_t magic2;
};
#define MASTER_MAGIC1 (0x67452301)
#define MASTER_MAGIC2 (0xEFCDAB89)
#define MASTER_FLAG_MRDY (0x01)
/* little-endian */
struct spi_slave_response
{
uint8_t reserve1;
uint8_t flag: 4;
uint8_t type: 4;
uint8_t slave_rx_buf: 4;
uint8_t slave_tx_buf: 4;
uint8_t reserve2;
uint16_t seq;
uint16_t S2M_len; // slave to master data len.
uint32_t magic1;
uint32_t magic2;
};
#define SLAVE_MAGIC1 (0x98BADCFE)
#define SLAVE_MAGIC2 (0x10325476)
#define SLAVE_FLAG_SRDY (0x01)
#define SLAVE_DATA_FULL (0x01)
/* spi buffer configure. */
#define SPI_MAX_DATA_LEN 1520
#define SPI_TX_POOL_SIZE 4
#define SPI_RX_POOL_SIZE 4
/* The slave interrupts wait timeout */
#define SLAVE_INT_TIMEOUT 100
typedef enum
{
RW007_SLAVE_INT = 1,
RW007_MASTER_DATA = 1<<1,
} wifi_event;
typedef enum
{
DATA_TYPE_STA_ETH_DATA = 1,
DATA_TYPE_AP_ETH_DATA,
DATA_TYPE_PROMISC_ETH_DATA,
DATA_TYPE_CMD,
DATA_TYPE_RESP,
DATA_TYPE_CB,
} app_data_type_t;
struct spi_data_packet
{
uint32_t data_len; /* length for buffer */
uint32_t data_type; /* app_data_type_t */
char buffer[SPI_MAX_DATA_LEN];
};
typedef struct rw007_ap_info_value
{
struct rt_wlan_info info;
char passwd[RT_WLAN_PASSWORD_MAX_LENGTH];
} * rw007_ap_info_value_t;
/* littel endian */
typedef struct rw007_cmd
{
uint32_t cmd;
uint32_t len;
/* command parameter */
union
{
uint32_t int_value;
uint8_t mac_value[8]; /* padding 2bytes */
struct rw007_ap_info_value ap_info_value;
char string_value[UINT16_MAX];
} value;
} * rw007_cmd_t;
struct rw007_resp
{
uint32_t cmd;
uint32_t len;
int32_t result; /* result of CMD. */
/* response value */
union
{
uint32_t int_value;
uint8_t mac_value[8]; /* padding 2bytes */
struct rw007_ap_info_value ap_info_value;
char string_value[UINT16_MAX];
} value;
};
/* tools */
#define node_entry(node, type, member) ((type *)((char *)(node) - (unsigned long)(&((type *)0)->member)))
#define member_offset(type, member) ((unsigned long)(&((type *)0)->member))
#define MAX_SPI_PACKET_SIZE (member_offset(struct spi_data_packet, buffer) + SPI_MAX_DATA_LEN)
typedef enum
{
RW00x_CMD_INIT = 0x00,
RW00x_CMD_SET_MODE,
RW00x_CMD_MAC_GET,
RW00x_CMD_MAC_SET,
RW00x_CMD_GET_SN,
RW00x_CMD_GET_VSR,
RW00x_CMD_SCAN,
RW00x_CMD_JOIN,
RW00x_CMD_SOFTAP,
RW00x_CMD_DISCONNECT,
RW00x_CMD_AP_STOP,
RW00x_CMD_AP_DEAUTH,
RW00x_CMD_SCAN_STOP,
RW00x_CMD_GET_RSSI,
RW00x_CMD_SET_PWR_SAVE,
RW00x_CMD_GET_PWR_SAVE,
RW00x_CMD_CFG_PROMISC,
RW00x_CMD_CFG_FILTER,
RW00x_CMD_SET_CHANNEL,
RW00x_CMD_GET_CHANNEL,
RW00x_CMD_SET_COUNTRY,
RW00x_CMD_GET_COUNTRY,
RW00x_CMD_AP_MAC_GET,
RW00x_CMD_AP_MAC_SET,
RW00x_CMD_MAX_NUM
}RW00x_CMD;
struct rw007_spi
{
/* Device handle for spi device */
struct rt_spi_device *spi_device;
/* Tx mempool and mailbox */
struct rt_mempool spi_tx_mp;
ALIGN(RT_ALIGN_SIZE)
rt_uint8_t spi_tx_mempool[(sizeof(struct spi_data_packet) + 4) * SPI_TX_POOL_SIZE];
struct rt_mailbox spi_tx_mb;
rt_ubase_t spi_tx_mb_pool[SPI_TX_POOL_SIZE + 1];
/* Rx mempool and mailbox */
struct rt_mempool spi_rx_mp;
ALIGN(RT_ALIGN_SIZE)
rt_uint8_t spi_rx_mempool[(sizeof(struct spi_data_packet) + 4) * SPI_RX_POOL_SIZE];
struct rt_mailbox spi_rx_mb;
rt_ubase_t spi_rx_mb_pool[SPI_RX_POOL_SIZE + 1];
/* response event */
rt_event_t rw007_cmd_event;
/* response data */
struct rw007_resp *resp[RW00x_CMD_MAX_NUM];
};
#define RW00x_CMD_RESP_EVENT(n) (0x01UL << n)
struct rw007_wifi
{
/* inherit from ethernet device */
struct rt_wlan_device *wlan;
/* spi transfer layer handle */
struct rw007_spi * hspi;
};
/* porting */
extern void spi_wifi_hw_init(void);
/* end porting */
/* api exclude in wlan framework */
extern rt_err_t rw007_sn_get(char sn[24]);
extern rt_err_t rw007_version_get(char version[16]);
/* end api exclude in wlan framework */
extern rt_err_t rt_hw_wifi_init(const char *spi_device_name);
#endif /* SPI_WIFI_H_INCLUDED */

View File

@ -0,0 +1,873 @@
/*
* COPYRIGHT (C) 2018, Real-Thread Information Technology Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2014-07-31 aozima the first version
* 2014-09-18 aozima update command & response.
* 2017-07-28 armink fix auto reconnect feature
* 2018-12-24 zyh porting rw007 from rw009
* 2019-02-25 zyh porting rw007 to wlan
* 2020-02-28 shaoguoji add spi transfer retry
* 2020-07-09 zj refactor the rw007
*/
#include <rtthread.h>
#include <string.h>
#ifndef RW007_LOG_LEVEL
#define RW007_LOG_LEVEL DBG_LOG
#endif
#define DBG_ENABLE
#define DBG_SECTION_NAME "[RW007]"
#define DBG_LEVEL RW007_LOG_LEVEL
#define DBG_COLOR
#include <rtdbg.h>
#include "spi_wifi_rw007.h"
static struct rw007_spi rw007_spi;
static struct rw007_wifi wifi_sta, wifi_ap;
static struct rt_event spi_wifi_data_event;
static rt_bool_t inited = RT_FALSE;
#ifdef WLAN_DEV_MONITOR
typedef struct
{
rt_uint32_t total;
rt_uint32_t lose;
rt_uint32_t retry;
rt_uint32_t first_stage_err;
rt_uint32_t second_stage_err;
} net_packet;
net_packet packet;
#endif
static int wifi_data_transfer(struct rw007_spi *dev, uint16_t seq, uint8_t *rx_buffer)
{
static const struct spi_data_packet *send_packet = RT_NULL;
struct spi_master_request cmd;
struct spi_slave_response resp;
struct rt_spi_message message;
struct rt_spi_device *rt_spi_device = dev->spi_device;
rt_uint32_t max_data_len = 0;
/* Clear cmd */
rt_memset(&cmd, 0, sizeof(cmd));
cmd.type = master_cmd_phase;
cmd.seq = seq;
/* Set magic word */
cmd.magic1 = MASTER_MAGIC1;
cmd.magic2 = MASTER_MAGIC2;
/* If the buffer is not full, Set master ready flag bit */
if(rx_buffer != RT_NULL)
{
cmd.flag |= MASTER_FLAG_MRDY;
}
if (send_packet == RT_NULL)
{
/* Check to see if any data needs to be sent */
if (rt_mb_recv(&dev->spi_tx_mb, (rt_ubase_t *)&send_packet, RT_WAITING_NO) != RT_EOK)
{
send_packet = RT_NULL;
}
}
/* Set length for master to slave when data ready*/
if (send_packet != RT_NULL)
{
/* Invalid data packet */
if((send_packet->data_len == 0) || (send_packet->data_len > SPI_MAX_DATA_LEN))
{
rt_mp_free((void *)send_packet);
send_packet = RT_NULL;
}
else
{
cmd.M2S_len = send_packet->data_len + member_offset(struct spi_data_packet, buffer);
}
}
/* Stage 1: Send command to rw007 */
rt_memset(&resp, 0, sizeof(resp));
rt_spi_transfer(rt_spi_device, &cmd, &resp, sizeof(resp));
/* Clear event */
rt_event_recv(&spi_wifi_data_event,
RW007_SLAVE_INT,
RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
RT_WAITING_NO,
RT_NULL);
/* checkout Stage 1 slave status */
if ((resp.magic1 != SLAVE_MAGIC1) || (resp.magic2 != SLAVE_MAGIC2) || (resp.type != slave_cmd_phase))
{
#ifdef WLAN_DEV_MONITOR
packet.first_stage_err++;
#endif
LOG_E("The wifi Stage 1 status %x %x %x %d\r", resp.magic1, resp.magic2, resp.type, cmd.seq);
goto _cmderr;
}
/* receive first event */
if (rt_event_recv(&spi_wifi_data_event,
RW007_SLAVE_INT,
RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
SLAVE_INT_TIMEOUT,
RT_NULL) != RT_EOK)
{
LOG_E("The wifi slave response timed out\r");
}
/* Stage 2: Receive response from rw007 */
cmd.type = master_data_phase; //data Stage
rt_memset(&resp, 0, sizeof(resp));
message.send_buf = &cmd;
message.recv_buf = &resp;
message.length = sizeof(resp);
message.cs_take = 1;
message.cs_release = 0;
/* Start a SPI transmit */
rt_spi_take_bus(rt_spi_device);
/* Receive response from rw007 */
rt_spi_device->bus->ops->xfer(rt_spi_device, &message);
/* Check response's magic word and seq */
if ((resp.magic1 != SLAVE_MAGIC1) || (resp.magic2 != SLAVE_MAGIC2) || (resp.seq != seq) || (resp.type != slave_data_phase))
{
#ifdef WLAN_DEV_MONITOR
packet.second_stage_err++;
#endif
LOG_E("The wifi Stage 2 status %x %x %x %x %d %d\r", resp.magic1, resp.magic2, resp.seq, resp.type, resp.S2M_len, cmd.seq);
goto _txerr;
}
/* Check rw007's data ready flag */
if (resp.flag & SLAVE_FLAG_SRDY)
{
max_data_len = cmd.M2S_len;
}
if (resp.S2M_len > MAX_SPI_PACKET_SIZE)
{
/* Drop error data */
resp.S2M_len = 0;
}
if (resp.S2M_len > max_data_len)
{
max_data_len = resp.S2M_len;
}
/* Setup message */
if((resp.S2M_len == 0) && (rx_buffer != RT_NULL))
{
rt_mp_free(rx_buffer);
rx_buffer = RT_NULL;
}
message.send_buf = send_packet;
message.recv_buf = rx_buffer;
message.length = RT_ALIGN(max_data_len, 4);/* align clk to word */
message.cs_take = 0;
message.cs_release = 1;
/* Transmit data */
rt_spi_device->bus->ops->xfer(rt_spi_device, &message);
/* End a SPI transmit */
rt_spi_release_bus(rt_spi_device);
/* Free send data space */
if ((resp.flag & SLAVE_FLAG_SRDY) && (send_packet != RT_NULL))
{
rt_mp_free((void *)send_packet);
send_packet = RT_NULL;
}
/* Parse recevied data */
if(rx_buffer)
{
rt_mb_send(&dev->spi_rx_mb, (rt_ubase_t)rx_buffer);
}
/* receive data end event */
if (rt_event_recv(&spi_wifi_data_event,
RW007_SLAVE_INT,
RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
SLAVE_INT_TIMEOUT,
RT_NULL) != RT_EOK)
{
LOG_E("The wifi slave data response timed out\r");
}
/* The slave has data */
if (resp.slave_tx_buf > 0)
{
return TRANSFER_DATA_CONTINUE;
}
return TRANSFER_DATA_SUCCESS;
_txerr:
/* END SPI transfer */
message.send_buf = RT_NULL;
message.recv_buf = RT_NULL;
message.length = 0;
message.cs_take = 0;
message.cs_release = 1;
rt_spi_device->bus->ops->xfer(rt_spi_device, &message);
rt_spi_release_bus(rt_spi_device); // End a SPI transmit
_cmderr:
rt_thread_delay(1);
return TRANSFER_DATA_ERROR;
}
static int spi_wifi_transfer(struct rw007_spi *dev)
{
static uint16_t cmd_seq = 0;
int result = TRANSFER_DATA_SUCCESS;
uint8_t * rx_buffer = rt_mp_alloc(&dev->spi_rx_mp, RT_WAITING_NO);
int32_t retry;
/* Generate the transmission sequence number */
cmd_seq++;
if (cmd_seq >= 65534)
{
cmd_seq = 1;
}
#ifdef WLAN_DEV_MONITOR
packet.total++;
#endif
/* set retry count */
retry = 3;
while (retry > 0)
{
result = wifi_data_transfer(dev, cmd_seq, rx_buffer);
if (result != TRANSFER_DATA_ERROR)
{
break;
}
retry--;
#ifdef WLAN_DEV_MONITOR
packet.retry++;
#endif
}
/* Receive response from rw007 error */
if (retry <= 0)
{
#ifdef WLAN_DEV_MONITOR
packet.lose++;
#endif
LOG_E("rw007 transfer failed\r");
goto _err;
}
return result;
_err:
if(rx_buffer)
{
rt_mp_free((void *)rx_buffer);
}
return TRANSFER_DATA_ERROR;
}
static void wifi_data_process_thread_entry(void *parameter)
{
const struct spi_data_packet *data_packet = RT_NULL;
struct rw007_spi *dev = (struct rw007_spi *)parameter;
while(1)
{
/* get the mempool memory for recv data package */
if(rt_mb_recv(&dev->spi_rx_mb, (rt_ubase_t *)&data_packet, RT_WAITING_FOREVER) == RT_EOK)
{
if (data_packet->data_type == DATA_TYPE_STA_ETH_DATA)
{
/* Ethernet package from station device */
rt_wlan_dev_report_data(wifi_sta.wlan, (void *)data_packet->buffer, data_packet->data_len);
}
else if (data_packet->data_type == DATA_TYPE_AP_ETH_DATA)
{
/* Ethernet package from ap device */
rt_wlan_dev_report_data(wifi_ap.wlan, (void *)data_packet->buffer, data_packet->data_len);
}
else if (data_packet->data_type == DATA_TYPE_PROMISC_ETH_DATA)
{
/* air wifi package from promisc */
rt_wlan_dev_promisc_handler(wifi_sta.wlan, (void *)data_packet->buffer, data_packet->data_len);
}
/* event callback */
else if(data_packet->data_type == DATA_TYPE_CB)
{
struct rw007_resp * resp = (struct rw007_resp *)data_packet->buffer;
if(resp->cmd == RT_WLAN_DEV_EVT_SCAN_REPORT)
{
/* parse scan report event data */
struct rt_wlan_buff buff;
struct rt_wlan_info * wlan_info;
wlan_info = (struct rt_wlan_info *)&resp->value;
buff.data = wlan_info;
buff.len = sizeof(struct rt_wlan_info);
/* indicate scan report event */
rt_wlan_dev_indicate_event_handle(wifi_sta.wlan, RT_WLAN_DEV_EVT_SCAN_REPORT, &buff);
}
else
{
if(resp->cmd == RT_WLAN_DEV_EVT_AP_START || resp->cmd == RT_WLAN_DEV_EVT_AP_STOP ||
resp->cmd == RT_WLAN_DEV_EVT_AP_ASSOCIATED || resp->cmd == RT_WLAN_DEV_EVT_AP_DISASSOCIATED)
{
/* indicate ap device event */
rt_wlan_dev_indicate_event_handle(wifi_ap.wlan, (rt_wlan_dev_event_t)resp->cmd, RT_NULL);
}
else
{
/* indicate sta device event */
rt_wlan_dev_indicate_event_handle(wifi_sta.wlan, (rt_wlan_dev_event_t)resp->cmd, RT_NULL);
}
}
}
else if (data_packet->data_type == DATA_TYPE_RESP)
{
/* parse cmd's response */
struct rw007_resp * resp = (struct rw007_resp *)data_packet->buffer;
if(resp->cmd < RW00x_CMD_MAX_NUM)
{
if(dev->resp[resp->cmd])
{
rt_free(dev->resp[resp->cmd]);
}
/* stash response result */
dev->resp[resp->cmd] = rt_malloc(MAX_SPI_PACKET_SIZE);
if(dev->resp[resp->cmd])
{
rt_memcpy(dev->resp[resp->cmd], resp, MAX_SPI_PACKET_SIZE);
/* notify response arrived */
rt_event_send(dev->rw007_cmd_event, RW00x_CMD_RESP_EVENT(resp->cmd));
}
}
}
/* free recv mempool memory */
rt_mp_free((void *)data_packet);
}
}
}
static void spi_wifi_data_thread_entry(void *parameter)
{
rt_bool_t empty_read = RT_TRUE;
rt_uint32_t event;
int state;
while (1)
{
/* receive first event */
if (rt_event_recv(&spi_wifi_data_event,
RW007_MASTER_DATA|
RW007_SLAVE_INT,
RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR,
RT_WAITING_FOREVER,
&event) != RT_EOK)
{
continue;
}
/* transfer */
state = spi_wifi_transfer(&rw007_spi);
/* Try reading again */
if(state == TRANSFER_DATA_CONTINUE)
{
rt_event_send(&spi_wifi_data_event, RW007_SLAVE_INT);
empty_read = RT_TRUE;
}
else
{
if ((state == TRANSFER_DATA_SUCCESS) && (empty_read == RT_TRUE))
{
rt_event_send(&spi_wifi_data_event, RW007_SLAVE_INT);
empty_read = RT_FALSE;
}
else
{
empty_read = RT_TRUE;
}
}
}
}
rt_inline struct rw007_wifi *wifi_get_dev_by_wlan(struct rt_wlan_device *wlan)
{
if (wlan == wifi_sta.wlan)
{
return &wifi_sta;
}
if (wlan == wifi_ap.wlan)
{
return &wifi_ap;
}
return RT_NULL;
}
rt_inline void spi_send_cmd(struct rw007_spi * hspi, RW00x_CMD COMMAND, void * buffer, rt_uint32_t len)
{
struct spi_data_packet * data_packet;
struct rw007_cmd * cmd;
data_packet = rt_mp_alloc(&hspi->spi_tx_mp, RT_WAITING_FOREVER);
data_packet->data_type = DATA_TYPE_CMD;
cmd = (struct rw007_cmd *)data_packet->buffer;
cmd->cmd = COMMAND;
cmd->len = len;
if(cmd->len)
{
rt_memcpy(&cmd->value, buffer, cmd->len);
}
data_packet->data_len = member_offset(struct rw007_cmd, value) + cmd->len;
rt_mb_send(&hspi->spi_tx_mb, (rt_ubase_t)data_packet);
rt_event_send(&spi_wifi_data_event, RW007_MASTER_DATA);
}
rt_inline rt_err_t spi_set_data(struct rt_wlan_device *wlan, RW00x_CMD COMMAND, void * buffer, rt_uint32_t len)
{
struct rw007_spi * hspi = wifi_get_dev_by_wlan(wlan)->hspi;
rt_uint32_t result_event;
rt_err_t result = RT_EOK;
spi_send_cmd(hspi, COMMAND, buffer, len);
if(rt_event_recv(hspi->rw007_cmd_event,
RW00x_CMD_RESP_EVENT(COMMAND),
RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
rt_tick_from_millisecond(10000),
&result_event) != RT_EOK)
{
return -RT_ETIMEOUT;
}
if(hspi->resp[COMMAND])
{
result = hspi->resp[COMMAND]->result;
rt_free(hspi->resp[COMMAND]);
hspi->resp[COMMAND] = RT_NULL;
return result;
}
return RT_EOK;
}
rt_inline rt_err_t spi_get_data(struct rt_wlan_device *wlan, RW00x_CMD COMMAND, void * buffer, rt_uint32_t *len)
{
struct rw007_spi * hspi = wifi_get_dev_by_wlan(wlan)->hspi;
rt_uint32_t result_event;
rt_err_t result = RT_EOK;
spi_send_cmd(hspi, COMMAND, RT_NULL, 0);
if(rt_event_recv(hspi->rw007_cmd_event,
RW00x_CMD_RESP_EVENT(COMMAND),
RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR,
rt_tick_from_millisecond(10000),
&result_event) != RT_EOK)
{
return -RT_ETIMEOUT;
}
if(hspi->resp[COMMAND])
{
*len = hspi->resp[COMMAND]->len;
rt_memcpy(buffer, &hspi->resp[COMMAND]->value, hspi->resp[COMMAND]->len);
result = hspi->resp[COMMAND]->result;
rt_free(hspi->resp[COMMAND]);
hspi->resp[COMMAND] = RT_NULL;
return result;
}
return RT_EOK;
}
rt_err_t rw007_sn_get(char sn[24])
{
rt_uint32_t size_of_data;
return spi_get_data(wifi_sta.wlan, RW00x_CMD_GET_SN, sn, &size_of_data);
}
rt_err_t rw007_version_get(char version[16])
{
rt_uint32_t size_of_data;
return spi_get_data(wifi_sta.wlan, RW00x_CMD_GET_VSR, version, &size_of_data);
}
static rt_err_t wlan_init(struct rt_wlan_device *wlan)
{
if(inited == RT_FALSE)
{
inited = RT_TRUE;
return spi_set_data(wlan, RW00x_CMD_INIT, RT_NULL, 0);
}
return RT_EOK;
}
static rt_err_t wlan_mode(struct rt_wlan_device *wlan, rt_wlan_mode_t mode)
{
return spi_set_data(wlan, RW00x_CMD_SET_MODE, &mode, sizeof(mode));
}
static rt_err_t wlan_scan(struct rt_wlan_device *wlan, struct rt_scan_info *scan_info)
{
return spi_set_data(wlan, RW00x_CMD_SCAN, RT_NULL, 0);
}
static rt_err_t wlan_join(struct rt_wlan_device *wlan, struct rt_sta_info *sta_info)
{
struct rw007_ap_info_value value;
value.info.security = sta_info->security;
value.info.band = RT_802_11_BAND_2_4GHZ;
value.info.datarate = 0;
value.info.channel = sta_info->channel;
value.info.hidden = 0;
value.info.rssi = 0;
value.info.ssid = sta_info->ssid;
rt_memcpy(value.info.bssid, sta_info->bssid, 6);
strncpy(value.passwd, (const char *)&sta_info->key.val[0], sta_info->key.len);
value.passwd[sta_info->key.len] = '\0';
return spi_set_data(wlan, RW00x_CMD_JOIN, &value, sizeof(value));
}
static rt_err_t wlan_softap(struct rt_wlan_device *wlan, struct rt_ap_info *ap_info)
{
struct rw007_ap_info_value value;
value.info.security = ap_info->security;
value.info.band = RT_802_11_BAND_2_4GHZ;
value.info.datarate = 0;
value.info.channel = ap_info->channel;
value.info.hidden = ap_info->hidden;
value.info.rssi = 0;
value.info.ssid = ap_info->ssid;
strncpy(value.passwd, (const char *)&ap_info->key.val[0], ap_info->key.len);
value.passwd[ap_info->key.len] = '\0';
return spi_set_data(wlan, RW00x_CMD_SOFTAP, &value, sizeof(value));
}
static rt_err_t wlan_disconnect(struct rt_wlan_device *wlan)
{
return spi_set_data(wlan, RW00x_CMD_DISCONNECT, RT_NULL, 0);
}
static rt_err_t wlan_ap_stop(struct rt_wlan_device *wlan)
{
return spi_set_data(wlan, RW00x_CMD_AP_STOP, RT_NULL, 0);
}
static rt_err_t wlan_ap_deauth(struct rt_wlan_device *wlan, rt_uint8_t mac[])
{
return spi_set_data(wlan, RW00x_CMD_AP_DEAUTH, mac, 6);
}
static rt_err_t wlan_scan_stop(struct rt_wlan_device *wlan)
{
return spi_set_data(wlan, RW00x_CMD_SCAN_STOP, RT_NULL, 0);
}
static int wlan_get_rssi(struct rt_wlan_device *wlan)
{
int rssi = -1;
rt_uint32_t size_of_data;
spi_get_data(wlan, RW00x_CMD_GET_RSSI, &rssi, &size_of_data);
return rssi;
}
static rt_err_t wlan_set_powersave(struct rt_wlan_device *wlan, int level)
{
return spi_set_data(wlan, RW00x_CMD_SET_PWR_SAVE, &level, sizeof(level));
}
static int wlan_get_powersave(struct rt_wlan_device *wlan)
{
int level = -1;
rt_uint32_t size_of_data;
spi_get_data(wlan, RW00x_CMD_GET_PWR_SAVE, &level, &size_of_data);
return level;
}
static rt_err_t wlan_cfg_promisc(struct rt_wlan_device *wlan, rt_bool_t start)
{
return spi_set_data(wlan, RW00x_CMD_CFG_PROMISC, &start, sizeof(start));
}
static rt_err_t wlan_cfg_filter(struct rt_wlan_device *wlan, struct rt_wlan_filter *filter)
{
return -RT_ENOSYS;
}
static rt_err_t wlan_set_channel(struct rt_wlan_device *wlan, int channel)
{
return spi_set_data(wlan, RW00x_CMD_SET_CHANNEL, &channel, sizeof(channel));
}
static int wlan_get_channel(struct rt_wlan_device *wlan)
{
int channel = -1;
rt_uint32_t size_of_data;
spi_get_data(wlan, RW00x_CMD_GET_CHANNEL, &channel, &size_of_data);
return channel;
}
static rt_err_t wlan_set_country(struct rt_wlan_device *wlan, rt_country_code_t country_code)
{
return spi_set_data(wlan, RW00x_CMD_SET_COUNTRY, &country_code, sizeof(country_code));
}
static rt_country_code_t wlan_get_country(struct rt_wlan_device *wlan)
{
rt_country_code_t code;
rt_uint32_t size_of_data;
spi_get_data(wlan, RW00x_CMD_GET_COUNTRY, &code, &size_of_data);
return code;
}
static rt_err_t wlan_set_mac(struct rt_wlan_device *wlan, rt_uint8_t mac[])
{
if(wlan == wifi_sta.wlan)
{
return spi_set_data(wlan, RW00x_CMD_MAC_SET, mac, 6);
}
return spi_set_data(wlan, RW00x_CMD_AP_MAC_SET, mac, 6);
}
static rt_err_t wlan_get_mac(struct rt_wlan_device *wlan, rt_uint8_t mac[])
{
rt_uint32_t size_of_data;
if(wlan == wifi_sta.wlan)
{
return spi_get_data(wlan, RW00x_CMD_MAC_GET, mac, &size_of_data);
}
return spi_get_data(wlan, RW00x_CMD_AP_MAC_GET, mac, &size_of_data);
}
static int wlan_send(struct rt_wlan_device *wlan, void *buff, int len)
{
struct rw007_spi * hspi = wifi_get_dev_by_wlan(wlan)->hspi;
struct spi_data_packet * data_packet;
if(wlan == RT_NULL)
{
return -1;
}
data_packet = rt_mp_alloc(&hspi->spi_tx_mp, RT_WAITING_FOREVER);
if (wlan == wifi_sta.wlan)
{
data_packet->data_type = DATA_TYPE_STA_ETH_DATA;
}
else
{
data_packet->data_type = DATA_TYPE_AP_ETH_DATA;
}
data_packet->data_len = len;
rt_memcpy(data_packet->buffer, buff, len);
rt_mb_send(&hspi->spi_tx_mb, (rt_ubase_t)data_packet);
rt_event_send(&spi_wifi_data_event, RW007_MASTER_DATA);
return len;
}
const static struct rt_wlan_dev_ops ops =
{
.wlan_init = wlan_init,
.wlan_mode = wlan_mode,
.wlan_scan = wlan_scan,
.wlan_join = wlan_join,
.wlan_softap = wlan_softap,
.wlan_disconnect = wlan_disconnect,
.wlan_ap_stop = wlan_ap_stop,
.wlan_ap_deauth = wlan_ap_deauth,
.wlan_scan_stop = wlan_scan_stop,
.wlan_get_rssi = wlan_get_rssi,
.wlan_set_powersave = wlan_set_powersave,
.wlan_get_powersave = wlan_get_powersave,
.wlan_cfg_promisc = wlan_cfg_promisc,
.wlan_cfg_filter = wlan_cfg_filter,
.wlan_set_channel = wlan_set_channel,
.wlan_get_channel = wlan_get_channel,
.wlan_set_country = wlan_set_country,
.wlan_get_country = wlan_get_country,
.wlan_set_mac = wlan_set_mac,
.wlan_get_mac = wlan_get_mac,
.wlan_recv = RT_NULL,
.wlan_send = wlan_send,
};
rt_err_t rt_hw_wifi_init(const char *spi_device_name)
{
static struct rt_wlan_device wlan_sta, wlan_ap;
rt_err_t ret;
wifi_sta.wlan = &wlan_sta;
wifi_sta.hspi = &rw007_spi;
wifi_ap.wlan = &wlan_ap;
wifi_ap.hspi = &rw007_spi;
/* align and struct size check. */
RT_ASSERT((SPI_MAX_DATA_LEN & 0x03) == 0);
memset(&rw007_spi, 0, sizeof(struct rw007_spi));
rw007_spi.spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name);
if (rw007_spi.spi_device == RT_NULL)
{
LOG_E("spi device %s not found!\r", spi_device_name);
return -RT_ENOSYS;
}
/* config spi */
{
struct rt_spi_configuration cfg;
cfg.data_width = 8;
cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible: Mode 0. */
cfg.max_hz = RW007_SPI_MAX_HZ; /* 15M 007 max 30M */
rt_spi_configure(rw007_spi.spi_device, &cfg);
}
/* init spi send mempool */
rt_mp_init(&rw007_spi.spi_tx_mp,
"spi_tx",
&rw007_spi.spi_tx_mempool[0],
sizeof(rw007_spi.spi_tx_mempool),
sizeof(struct spi_data_packet));
/* init spi send mailbox */
rt_mb_init(&rw007_spi.spi_tx_mb,
"spi_tx",
&rw007_spi.spi_tx_mb_pool[0],
SPI_TX_POOL_SIZE,
RT_IPC_FLAG_PRIO);
/* init spi recv mempool */
rt_mp_init(&rw007_spi.spi_rx_mp,
"spi_rx",
&rw007_spi.spi_rx_mempool[0],
sizeof(rw007_spi.spi_rx_mempool),
sizeof(struct spi_data_packet));
/* init spi recv mailbox */
rt_mb_init(&rw007_spi.spi_rx_mb,
"spi_rx",
&rw007_spi.spi_rx_mb_pool[0],
SPI_RX_POOL_SIZE,
RT_IPC_FLAG_PRIO);
/* init spi data notify event */
rt_event_init(&spi_wifi_data_event, "wifi", RT_IPC_FLAG_FIFO);
rw007_spi.rw007_cmd_event = rt_event_create("wifi_cmd", RT_IPC_FLAG_FIFO);
/* register wlan device for ap */
ret = rt_wlan_dev_register(&wlan_ap, RT_WLAN_DEVICE_AP_NAME, &ops, 0, &wifi_ap);
if (ret != RT_EOK)
{
return ret;
}
/* register wlan device for sta */
ret = rt_wlan_dev_register(&wlan_sta, RT_WLAN_DEVICE_STA_NAME, &ops, 0, &wifi_sta);
if (ret != RT_EOK)
{
return ret;
}
{
rt_thread_t tid;
/* Create package parse thread */
tid = rt_thread_create("wifi_handle",
wifi_data_process_thread_entry,
&rw007_spi,
2048,
8,
20);
if(!tid)
{
return -RT_ERROR;
}
rt_thread_startup(tid);
/* Create wifi transfer thread */
tid = rt_thread_create("wifi_xfer",
spi_wifi_data_thread_entry,
RT_NULL,
2048,
9,
20);
if(!tid)
{
return -RT_ERROR;
}
rt_thread_startup(tid);
}
spi_wifi_hw_init();
return RT_EOK;
}
void spi_wifi_isr(int vector)
{
/* enter interrupt */
rt_interrupt_enter();
/* device has a package to ready transfer */
rt_event_send(&spi_wifi_data_event, RW007_SLAVE_INT);
/* leave interrupt */
rt_interrupt_leave();
}
#ifdef WLAN_DEV_MONITOR
int rw007_dump(int argc, char **argv)
{
if (argc == 1)
{
goto __usage;
}
if (strcmp(argv[1], "--show") == 0)
{
rt_kprintf("Wifi Device transmission information:\n");
rt_kprintf("Total packets : %d\n", packet.total);
rt_kprintf("Failed packets : %d\n", packet.lose);
rt_kprintf("Retry count : %d\n", packet.retry);
rt_kprintf("Stage 1 error : %d\n", packet.first_stage_err);
rt_kprintf("Stage 2 error : %d\n", packet.second_stage_err);
}
else if (strcmp(argv[1], "-h") == 0)
{
goto __usage;
}
else if (strcmp(argv[1], "-c") == 0)
{
rt_memset(&packet, 0, sizeof(packet));
}
return 0;
__usage:
rt_kprintf("Usage: wifi_dump [-s|-c]\n");
rt_kprintf("\n");
rt_kprintf("Miscellaneous:\n");
rt_kprintf(" -h print this message and quit\n");
rt_kprintf(" --show show information\n");
rt_kprintf(" -c Clear record data\n");
return 0;
}
#ifdef RT_USING_FINSH
#include <finsh.h>
MSH_CMD_EXPORT(rw007_dump, the rw007 Informations Viewer);
#endif
#endif