diff --git a/bsp/stm32f429-apollo/applications/application.c b/bsp/stm32f429-apollo/applications/application.c index 4760de9d41..a3201a0034 100644 --- a/bsp/stm32f429-apollo/applications/application.c +++ b/bsp/stm32f429-apollo/applications/application.c @@ -32,12 +32,18 @@ #include #include #include -#include "stm32f4xx_eth.h" +#include "drv_eth.h" #endif #ifdef RT_USING_GDB #include #endif + +#ifdef RT_USING_GUIENGINE +#include "rtgui_demo.h" +#include +#endif + //rt_module_t module_ptr; #define DATA_PATH "/Data" void rt_init_thread_entry(void* parameter) @@ -77,25 +83,29 @@ void rt_init_thread_entry(void* parameter) rt_kprintf("File System initialzation failed!\n"); } + /* mount sd card fat partition 0 as root directory */ + if (dfs_mount("W25Q256", "/spi", "elm", 0, 0) == 0) + { + rt_kprintf("spi flash mount to /spi !\n"); + } + else + { + rt_kprintf("spi flash mount to /spi failed!\n"); + } #endif /* RT_USING_DFS_ELMFAT */ -// module_ptr = rt_module_open("/hello.mo"); - #endif /* DFS */ - /* LwIP Initialization */ -#ifdef RT_USING_LWIP - { - extern void lwip_sys_init(void); + +#ifdef RT_USING_GUIENGINE + { + rt_device_t device; - /* register ethernetif device */ - eth_system_device_init(); - - rt_hw_stm32_eth_init(); - - /* init lwip system */ - lwip_sys_init(); - rt_kprintf("TCP/IP initialized!\n"); - } + device = rt_device_find("lcd"); + /* re-set graphic device */ + rtgui_graphic_set_device(device); + + rt_gui_demo_init(); + } #endif } int rt_application_init() diff --git a/bsp/stm32f429-apollo/applications/rtgui_demo.c b/bsp/stm32f429-apollo/applications/rtgui_demo.c new file mode 100644 index 0000000000..f553c1b50a --- /dev/null +++ b/bsp/stm32f429-apollo/applications/rtgui_demo.c @@ -0,0 +1,129 @@ +/* + * File : application.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "finsh.h" +#include "rtgui_demo.h" + +#define DEBUG + +#ifdef DEBUG +#define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__) +#else +#define DEBUG_PRINTF(...) +#endif + +#ifdef RT_USING_GUIENGINE + +struct rtgui_win *main_win; +rt_bool_t dc_event_handler(struct rtgui_object *object, rtgui_event_t *event); + +static void rt_gui_demo_entry(void *parameter) +{ + struct rtgui_app *app; + //struct rtgui_dc *dc; + + DEBUG_PRINTF("gui demo entry\n"); + + /* create gui app */ + app = rtgui_app_create("gui_demo"); + if (app == RT_NULL) + { + DEBUG_PRINTF("rtgui_app_create faild\n"); + return; + } + + /* create main window */ + main_win = rtgui_mainwin_create(RT_NULL, + "UiWindow", RTGUI_WIN_STYLE_NO_TITLE | RTGUI_WIN_STYLE_NO_BORDER); + if (main_win == RT_NULL) + { + DEBUG_PRINTF("main_win is null\n"); + rtgui_app_destroy(app); + return; + } + + rtgui_object_set_event_handler(RTGUI_OBJECT(main_win), dc_event_handler); + + DEBUG_PRINTF("rtgui_win_show\n"); + rtgui_win_show(main_win, RT_FALSE); + + DEBUG_PRINTF("rtgui_app_run\n"); + rtgui_app_run(app); + + DEBUG_PRINTF("rtgui_win_destroy\n"); + rtgui_win_destroy(main_win); + + DEBUG_PRINTF("rtgui_app_destroy\n"); + rtgui_app_destroy(app); +} + +rt_bool_t dc_event_handler(struct rtgui_object *object, rtgui_event_t *event) +{ + struct rtgui_widget *widget = RTGUI_WIDGET(object); + + if (event->type == RTGUI_EVENT_PAINT) + { + struct rtgui_dc *dc; + rtgui_rect_t rect; + + rt_kprintf("\r\n RTGUI_EVENT_PAINT \r\n"); + rtgui_win_event_handler(RTGUI_OBJECT(widget), event); + + rtgui_widget_get_rect(widget, &rect); + DEBUG_PRINTF("widget react x1: %d, y1: %d, x2: %d, y2: %d\r\n", + rect.x1, rect.y1, rect.x2, rect.y2); + + dc = rtgui_dc_begin_drawing(widget); + if(dc == RT_NULL) + { + DEBUG_PRINTF("\r\n dc is null \r\n"); + return RT_FALSE; + } + + rtgui_dc_draw_line(dc,0,0,240,320); + rtgui_dc_draw_line(dc,0,320,240,0); + //rtgui_dc_draw_text(dc, __DATE__, &rect); + rtgui_dc_draw_text_stroke(dc, __DATE__, &rect, HIGH_LIGHT, BLUE); + + rect.y1 += 20; + rect.y2 += 20; + rtgui_dc_draw_text_stroke(dc, __TIME__, &rect, HIGH_LIGHT, BLACK); + + + rtgui_dc_end_drawing(dc); + } + return RT_FALSE; +} + +int rt_gui_demo_init(void) +{ + rt_thread_t tid; + tid = rt_thread_create("mygui", + rt_gui_demo_entry, RT_NULL, + 2048, 25, 10); + + if (tid != RT_NULL) + rt_thread_startup(tid); + + return 0; +} +#endif /* RT_USING_GUIENGINE */ diff --git a/bsp/stm32f429-apollo/applications/rtgui_demo.h b/bsp/stm32f429-apollo/applications/rtgui_demo.h new file mode 100644 index 0000000000..e27f7b5609 --- /dev/null +++ b/bsp/stm32f429-apollo/applications/rtgui_demo.h @@ -0,0 +1,20 @@ +/* + * File : dc.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-06-02 tanek first version + */ +#ifndef __APP_GUI_DEMO_H__ +#define __APP_GUI_DEMO_H__ + +extern int rt_gui_demo_init(void); + +#endif + diff --git a/bsp/stm32f429-apollo/drivers/SConscript b/bsp/stm32f429-apollo/drivers/SConscript index b7213b6b80..71d829e41b 100644 --- a/bsp/stm32f429-apollo/drivers/SConscript +++ b/bsp/stm32f429-apollo/drivers/SConscript @@ -18,12 +18,24 @@ drv_mpu.c # add Ethernet drivers. if GetDepend('RT_USING_LWIP'): - src += ['stm32f4xx_eth.c'] + src += ['drv_eth.c', 'drv_iic.c', 'drv_pcf8574.c'] # add gpio drivers. if GetDepend('RT_USING_PIN'): src += ['gpio.c'] +# add spi drivers. +if GetDepend('RT_USING_SPI'): + src += ['drv_spi.c'] + +# add spi flash drivers. +if GetDepend('RT_USING_SFUD'): + src += ['drv_spi_flash.c'] + +# add lcd drivers. +if GetDepend('RT_USING_GUIENGINE'): + src += ['drv_lcd.c'] + CPPPATH = [cwd] group = DefineGroup('Drivers', src, depend = [''], CPPPATH = CPPPATH) diff --git a/bsp/stm32f429-apollo/drivers/board.h b/bsp/stm32f429-apollo/drivers/board.h index 5b3d6f206b..5090d04f1f 100644 --- a/bsp/stm32f429-apollo/drivers/board.h +++ b/bsp/stm32f429-apollo/drivers/board.h @@ -61,7 +61,7 @@ extern int __bss_end; // Console on USART: <0=> no console <1=>USART 1 <2=>USART 2 <3=> USART 3 // Default: 1 -#define STM32_CONSOLE_USART 2 +#define STM32_CONSOLE_USART 1 void rt_hw_board_init(void); diff --git a/bsp/stm32f429-apollo/drivers/drv_eth.c b/bsp/stm32f429-apollo/drivers/drv_eth.c new file mode 100644 index 0000000000..980083f396 --- /dev/null +++ b/bsp/stm32f429-apollo/drivers/drv_eth.c @@ -0,0 +1,596 @@ +/* + * File : application.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-06-08 tanek first implementation + */ +#include +#include +#include "lwipopts.h" +#include "board.h" +#include "drv_pcf8574.h" +#include +#include + +/* debug option */ +//#define DEBUG +//#define ETH_RX_DUMP +//#define ETH_TX_DUMP + +#ifdef DEBUG +#define STM32_ETH_PRINTF rt_kprintf +#else +#define STM32_ETH_PRINTF(...) +#endif + +/*网络引脚设置 RMII接口 + ETH_MDIO -------------------------> PA2 + ETH_MDC --------------------------> PC1 + ETH_RMII_REF_CLK------------------> PA1 + ETH_RMII_CRS_DV ------------------> PA7 + ETH_RMII_RXD0 --------------------> PC4 + ETH_RMII_RXD1 --------------------> PC5 + ETH_RMII_TX_EN -------------------> PB11 + ETH_RMII_TXD0 --------------------> PG13 + ETH_RMII_TXD1 --------------------> PG14 + ETH_RESET-------------------------> PCF8574扩展IO +*/ +#define ETH_MDIO_PORN GPIOA +#define ETH_MDIO_PIN GPIO_PIN_2 +#define ETH_MDC_PORN GPIOC +#define ETH_MDC_PIN GPIO_PIN_1 +#define ETH_RMII_REF_CLK_PORN GPIOA +#define ETH_RMII_REF_CLK_PIN GPIO_PIN_1 +#define ETH_RMII_CRS_DV_PORN GPIOA +#define ETH_RMII_CRS_DV_PIN GPIO_PIN_7 +#define ETH_RMII_RXD0_PORN GPIOC +#define ETH_RMII_RXD0_PIN GPIO_PIN_4 +#define ETH_RMII_RXD1_PORN GPIOC +#define ETH_RMII_RXD1_PIN GPIO_PIN_5 +#define ETH_RMII_TX_EN_PORN GPIOB +#define ETH_RMII_TX_EN_PIN GPIO_PIN_11 +#define ETH_RMII_TXD0_PORN GPIOG +#define ETH_RMII_TXD0_PIN GPIO_PIN_13 +#define ETH_RMII_TXD1_PORN GPIOG +#define ETH_RMII_TXD1_PIN GPIO_PIN_14 + +#define LAN8742A_PHY_ADDRESS 0x00 + +#define MAX_ADDR_LEN 6 +struct rt_stm32_eth +{ + /* inherit from ethernet device */ + struct eth_device parent; + + /* interface address info. */ + rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */ + + uint32_t ETH_Speed; /*!< @ref ETH_Speed */ + uint32_t ETH_Mode; /*!< @ref ETH_Duplex_Mode */ +}; + + +static ETH_DMADescTypeDef DMARxDscrTab[ETH_RXBUFNB], DMATxDscrTab[ETH_TXBUFNB]; +static rt_uint8_t Rx_Buff[ETH_RXBUFNB][ETH_MAX_PACKET_SIZE], Tx_Buff[ETH_TXBUFNB][ETH_MAX_PACKET_SIZE]; +static rt_bool_t tx_is_waiting = RT_FALSE; +static ETH_HandleTypeDef EthHandle; +static struct rt_stm32_eth stm32_eth_device; +static struct rt_semaphore tx_wait; + +/* interrupt service routine */ +void ETH_IRQHandler(void) +{ + /* enter interrupt */ + rt_interrupt_enter(); + + HAL_ETH_IRQHandler(&EthHandle); + + /* leave interrupt */ + rt_interrupt_leave(); +} + +void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth) +{ + if (tx_is_waiting == RT_TRUE) + { + tx_is_waiting = RT_FALSE; + rt_sem_release(&tx_wait); + } +} + +void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth) +{ + rt_err_t result; + result = eth_device_ready(&(stm32_eth_device.parent)); + if( result != RT_EOK ) + rt_kprintf("RX err =%d\n", result ); +} + +void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth) +{ + rt_kprintf("eth err\n"); +} + +static void phy_pin_reset(void) +{ + rt_base_t level; + + extern void delay_ms(rt_uint32_t nms); + + level = rt_hw_interrupt_disable(); + + rt_pcf8574_write_bit(ETH_RESET_IO, 1); + delay_ms(100); + rt_pcf8574_write_bit(ETH_RESET_IO, 0); + delay_ms(100); + + rt_hw_interrupt_enable(level); +} +#ifdef DEBUG +FINSH_FUNCTION_EXPORT(phy_pin_reset, phy hardware reset); +#endif + +/* initialize the interface */ +static rt_err_t rt_stm32_eth_init(rt_device_t dev) +{ + STM32_ETH_PRINTF("rt_stm32_eth_init...\n"); + + __HAL_RCC_ETH_CLK_ENABLE(); + + rt_pcf8574_init(); + phy_pin_reset(); + + /* ETHERNET Configuration --------------------------------------------------*/ + EthHandle.Instance = ETH; + EthHandle.Init.MACAddr = (rt_uint8_t*)&stm32_eth_device.dev_addr[0]; + EthHandle.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE; + EthHandle.Init.Speed = ETH_SPEED_100M; + EthHandle.Init.DuplexMode = ETH_MODE_FULLDUPLEX; + EthHandle.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII; + EthHandle.Init.RxMode = ETH_RXINTERRUPT_MODE; + EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE; + //EthHandle.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE; + EthHandle.Init.PhyAddress = LAN8742A_PHY_ADDRESS; + + HAL_ETH_DeInit(&EthHandle); + + /* configure ethernet peripheral (GPIOs, clocks, MAC, DMA) */ + if (HAL_ETH_Init(&EthHandle) == HAL_OK) + { + STM32_ETH_PRINTF("eth hardware init sucess...\n"); + } + else + { + STM32_ETH_PRINTF("eth hardware init faild...\n"); + } + + /* Initialize Tx Descriptors list: Chain Mode */ + HAL_ETH_DMATxDescListInit(&EthHandle, DMATxDscrTab, &Tx_Buff[0][0], ETH_TXBUFNB); + + /* Initialize Rx Descriptors list: Chain Mode */ + HAL_ETH_DMARxDescListInit(&EthHandle, DMARxDscrTab, &Rx_Buff[0][0], ETH_RXBUFNB); + + /* Enable MAC and DMA transmission and reception */ + if (HAL_ETH_Start(&EthHandle) == HAL_OK) + { + STM32_ETH_PRINTF("eth hardware start success...\n"); + } + else + { + STM32_ETH_PRINTF("eth hardware start faild...\n"); + } + + //phy_monitor_thread_entry(NULL); + + return RT_EOK; +} + +static rt_err_t rt_stm32_eth_open(rt_device_t dev, rt_uint16_t oflag) +{ + STM32_ETH_PRINTF("rt_stm32_eth_open...\n"); + return RT_EOK; +} + +static rt_err_t rt_stm32_eth_close(rt_device_t dev) +{ + STM32_ETH_PRINTF("rt_stm32_eth_close...\n"); + return RT_EOK; +} + +static rt_size_t rt_stm32_eth_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) +{ + STM32_ETH_PRINTF("rt_stm32_eth_read...\n"); + rt_set_errno(-RT_ENOSYS); + return 0; +} + +static rt_size_t rt_stm32_eth_write (rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) +{ + STM32_ETH_PRINTF("rt_stm32_eth_write...\n"); + rt_set_errno(-RT_ENOSYS); + return 0; +} + +static rt_err_t rt_stm32_eth_control(rt_device_t dev, rt_uint8_t cmd, void *args) +{ + STM32_ETH_PRINTF("rt_stm32_eth_control...\n"); + switch(cmd) + { + case NIOCTL_GADDR: + /* get mac address */ + if(args) rt_memcpy(args, stm32_eth_device.dev_addr, 6); + else return -RT_ERROR; + break; + + default : + break; + } + + return RT_EOK; +} + +/* ethernet device interface */ +/* transmit packet. */ +rt_err_t rt_stm32_eth_tx( rt_device_t dev, struct pbuf* p) +{ + rt_err_t ret = RT_ERROR; + HAL_StatusTypeDef state; + struct pbuf *q; + uint8_t *buffer = (uint8_t *)(EthHandle.TxDesc->Buffer1Addr); + __IO ETH_DMADescTypeDef *DmaTxDesc; + uint32_t framelength = 0; + uint32_t bufferoffset = 0; + uint32_t byteslefttocopy = 0; + uint32_t payloadoffset = 0; + + DmaTxDesc = EthHandle.TxDesc; + bufferoffset = 0; + + STM32_ETH_PRINTF("rt_stm32_eth_tx...\n"); + + /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */ + while ((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET) + { + rt_err_t result; + rt_uint32_t level; + + level = rt_hw_interrupt_disable(); + tx_is_waiting = RT_TRUE; + rt_hw_interrupt_enable(level); + + /* it's own bit set, wait it */ + result = rt_sem_take(&tx_wait, RT_WAITING_FOREVER); + if (result == RT_EOK) break; + if (result == -RT_ERROR) return -RT_ERROR; + } + + /* copy frame from pbufs to driver buffers */ + for(q = p; q != NULL; q = q->next) + { + /* Is this buffer available? If not, goto error */ + if((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET) + { + STM32_ETH_PRINTF("buffer not valid ...\n"); + ret = ERR_USE; + goto error; + } + + STM32_ETH_PRINTF("copy one frame\n"); + + /* Get bytes in current lwIP buffer */ + byteslefttocopy = q->len; + payloadoffset = 0; + + /* Check if the length of data to copy is bigger than Tx buffer size*/ + while( (byteslefttocopy + bufferoffset) > ETH_TX_BUF_SIZE ) + { + /* Copy data to Tx buffer*/ + memcpy( (uint8_t*)((uint8_t*)buffer + bufferoffset), (uint8_t*)((uint8_t*)q->payload + payloadoffset), (ETH_TX_BUF_SIZE - bufferoffset) ); + + /* Point to next descriptor */ + DmaTxDesc = (ETH_DMADescTypeDef *)(DmaTxDesc->Buffer2NextDescAddr); + + /* Check if the buffer is available */ + if((DmaTxDesc->Status & ETH_DMATXDESC_OWN) != (uint32_t)RESET) + { + STM32_ETH_PRINTF("dmatxdesc buffer not valid ...\n"); + ret = ERR_USE; + goto error; + } + + buffer = (uint8_t *)(DmaTxDesc->Buffer1Addr); + + byteslefttocopy = byteslefttocopy - (ETH_TX_BUF_SIZE - bufferoffset); + payloadoffset = payloadoffset + (ETH_TX_BUF_SIZE - bufferoffset); + framelength = framelength + (ETH_TX_BUF_SIZE - bufferoffset); + bufferoffset = 0; + } + + /* Copy the remaining bytes */ + memcpy( (uint8_t*)((uint8_t*)buffer + bufferoffset), (uint8_t*)((uint8_t*)q->payload + payloadoffset), byteslefttocopy ); + bufferoffset = bufferoffset + byteslefttocopy; + framelength = framelength + byteslefttocopy; + } + +#ifdef ETH_TX_DUMP + { + rt_uint32_t i; + rt_uint8_t *ptr = buffer; + + STM32_ETH_PRINTF("tx_dump, len:%d\r\n", p->tot_len); + for(i=0; itot_len; i++) + { + STM32_ETH_PRINTF("%02x ",*ptr); + ptr++; + + if(((i+1)%8) == 0) + { + STM32_ETH_PRINTF(" "); + } + if(((i+1)%16) == 0) + { + STM32_ETH_PRINTF("\r\n"); + } + } + STM32_ETH_PRINTF("\r\ndump done!\r\n"); + } +#endif + + /* Prepare transmit descriptors to give to DMA */ + STM32_ETH_PRINTF("transmit frame, length: %d\n", framelength); + state = HAL_ETH_TransmitFrame(&EthHandle, framelength); + if (state != HAL_OK) + { + STM32_ETH_PRINTF("eth transmit frame faild: %d\n", state); + } + + ret = ERR_OK; + +error: + + /* When Transmit Underflow flag is set, clear it and issue a Transmit Poll Demand to resume transmission */ + if ((EthHandle.Instance->DMASR & ETH_DMASR_TUS) != (uint32_t)RESET) + { + /* Clear TUS ETHERNET DMA flag */ + EthHandle.Instance->DMASR = ETH_DMASR_TUS; + + /* Resume DMA transmission*/ + EthHandle.Instance->DMATPDR = 0; + } + + return ret; +} + +/* reception packet. */ +struct pbuf *rt_stm32_eth_rx(rt_device_t dev) +{ + + struct pbuf *p = NULL; + struct pbuf *q = NULL; + HAL_StatusTypeDef state; + uint16_t len = 0; + uint8_t *buffer; + __IO ETH_DMADescTypeDef *dmarxdesc; + uint32_t bufferoffset = 0; + uint32_t payloadoffset = 0; + uint32_t byteslefttocopy = 0; + uint32_t i=0; + + STM32_ETH_PRINTF("rt_stm32_eth_rx\n"); + + /* Get received frame */ + state = HAL_ETH_GetReceivedFrame_IT(&EthHandle); + if (state != HAL_OK) + { + STM32_ETH_PRINTF("receive frame faild\n"); + return NULL; + } + + /* Obtain the size of the packet and put it into the "len" variable. */ + len = EthHandle.RxFrameInfos.length; + buffer = (uint8_t *)EthHandle.RxFrameInfos.buffer; + + STM32_ETH_PRINTF("receive frame len : %d\n", len); + + if (len > 0) + { + /* We allocate a pbuf chain of pbufs from the Lwip buffer pool */ + p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); + } + +#ifdef ETH_RX_DUMP + { + rt_uint32_t i; + rt_uint8_t *ptr = buffer; + + STM32_ETH_PRINTF("rx_dump, len:%d\r\n", p->tot_len); + for (i = 0; i < len; i++) + { + STM32_ETH_PRINTF("%02x ", *ptr); + ptr++; + + if (((i + 1) % 8) == 0) + { + STM32_ETH_PRINTF(" "); + } + if (((i + 1) % 16) == 0) + { + STM32_ETH_PRINTF("\r\n"); + } + } + STM32_ETH_PRINTF("\r\ndump done!\r\n"); + } +#endif + + if (p != NULL) + { + dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc; + bufferoffset = 0; + for(q = p; q != NULL; q = q->next) + { + byteslefttocopy = q->len; + payloadoffset = 0; + + /* Check if the length of bytes to copy in current pbuf is bigger than Rx buffer size*/ + while( (byteslefttocopy + bufferoffset) > ETH_RX_BUF_SIZE ) + { + /* Copy data to pbuf */ + memcpy( (uint8_t*)((uint8_t*)q->payload + payloadoffset), (uint8_t*)((uint8_t*)buffer + bufferoffset), (ETH_RX_BUF_SIZE - bufferoffset)); + + /* Point to next descriptor */ + dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr); + buffer = (uint8_t *)(dmarxdesc->Buffer1Addr); + + byteslefttocopy = byteslefttocopy - (ETH_RX_BUF_SIZE - bufferoffset); + payloadoffset = payloadoffset + (ETH_RX_BUF_SIZE - bufferoffset); + bufferoffset = 0; + } + /* Copy remaining data in pbuf */ + memcpy( (uint8_t*)((uint8_t*)q->payload + payloadoffset), (uint8_t*)((uint8_t*)buffer + bufferoffset), byteslefttocopy); + bufferoffset = bufferoffset + byteslefttocopy; + } + } + + /* Release descriptors to DMA */ + /* Point to first descriptor */ + dmarxdesc = EthHandle.RxFrameInfos.FSRxDesc; + /* Set Own bit in Rx descriptors: gives the buffers back to DMA */ + for (i=0; i< EthHandle.RxFrameInfos.SegCount; i++) + { + dmarxdesc->Status |= ETH_DMARXDESC_OWN; + dmarxdesc = (ETH_DMADescTypeDef *)(dmarxdesc->Buffer2NextDescAddr); + } + + /* Clear Segment_Count */ + EthHandle.RxFrameInfos.SegCount =0; + + /* When Rx Buffer unavailable flag is set: clear it and resume reception */ + if ((EthHandle.Instance->DMASR & ETH_DMASR_RBUS) != (uint32_t)RESET) + { + /* Clear RBUS ETHERNET DMA flag */ + EthHandle.Instance->DMASR = ETH_DMASR_RBUS; + /* Resume DMA reception */ + EthHandle.Instance->DMARPDR = 0; + } + + return p; +} + +static void NVIC_Configuration(void) +{ + /* Enable the Ethernet global Interrupt */ + HAL_NVIC_SetPriority(ETH_IRQn, 0x7, 0); + HAL_NVIC_EnableIRQ(ETH_IRQn); +} + +/* + * GPIO Configuration for ETH + */ +static void GPIO_Configuration(void) +{ + GPIO_InitTypeDef GPIO_InitStructure; + + STM32_ETH_PRINTF("GPIO_Configuration...\n"); + + /* Enable SYSCFG clock */ + __HAL_RCC_ETH_CLK_ENABLE(); + __HAL_RCC_GPIOA_CLK_ENABLE(); + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOG_CLK_ENABLE(); + + GPIO_InitStructure.Speed = GPIO_SPEED_HIGH; + GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; + GPIO_InitStructure.Alternate = GPIO_AF11_ETH; + GPIO_InitStructure.Pull = GPIO_NOPULL; + + GPIO_InitStructure.Pin = ETH_MDIO_PIN; + HAL_GPIO_Init(ETH_MDIO_PORN,&GPIO_InitStructure); + GPIO_InitStructure.Pin = ETH_MDC_PIN; + HAL_GPIO_Init(ETH_MDC_PORN,&GPIO_InitStructure); + + GPIO_InitStructure.Pin = ETH_RMII_REF_CLK_PIN; + HAL_GPIO_Init(ETH_RMII_REF_CLK_PORN,&GPIO_InitStructure); + GPIO_InitStructure.Pin = ETH_RMII_CRS_DV_PIN; + HAL_GPIO_Init(ETH_RMII_CRS_DV_PORN,&GPIO_InitStructure); + + GPIO_InitStructure.Pin = ETH_RMII_REF_CLK_PIN; + HAL_GPIO_Init(ETH_RMII_REF_CLK_PORN,&GPIO_InitStructure); + GPIO_InitStructure.Pin = ETH_RMII_CRS_DV_PIN; + HAL_GPIO_Init(ETH_RMII_CRS_DV_PORN,&GPIO_InitStructure); + + GPIO_InitStructure.Pin = ETH_RMII_RXD0_PIN; + HAL_GPIO_Init(ETH_RMII_RXD0_PORN,&GPIO_InitStructure); + GPIO_InitStructure.Pin = ETH_RMII_RXD1_PIN; + HAL_GPIO_Init(ETH_RMII_RXD1_PORN,&GPIO_InitStructure); + + GPIO_InitStructure.Pin = ETH_RMII_TX_EN_PIN; + HAL_GPIO_Init(ETH_RMII_TX_EN_PORN,&GPIO_InitStructure); + GPIO_InitStructure.Pin = ETH_RMII_TXD0_PIN; + HAL_GPIO_Init(ETH_RMII_TXD0_PORN,&GPIO_InitStructure); + GPIO_InitStructure.Pin = ETH_RMII_TXD1_PIN; + HAL_GPIO_Init(ETH_RMII_TXD1_PORN,&GPIO_InitStructure); + + HAL_NVIC_SetPriority(ETH_IRQn,1,0); + HAL_NVIC_EnableIRQ(ETH_IRQn); +} + + +void HAL_ETH_MspInit(ETH_HandleTypeDef *heth) +{ + GPIO_Configuration(); + NVIC_Configuration(); +} + +static int rt_hw_stm32_eth_init(void) +{ + rt_err_t state; + + stm32_eth_device.ETH_Speed = ETH_SPEED_100M; + stm32_eth_device.ETH_Mode = ETH_MODE_FULLDUPLEX; + + /* OUI 00-80-E1 STMICROELECTRONICS. */ + stm32_eth_device.dev_addr[0] = 0x00; + stm32_eth_device.dev_addr[1] = 0x80; + stm32_eth_device.dev_addr[2] = 0xE1; + /* generate MAC addr from 96bit unique ID (only for test). */ + stm32_eth_device.dev_addr[3] = *(rt_uint8_t*)(UID_BASE+4); + stm32_eth_device.dev_addr[4] = *(rt_uint8_t*)(UID_BASE+2); + stm32_eth_device.dev_addr[5] = *(rt_uint8_t*)(UID_BASE+0); + + stm32_eth_device.parent.parent.init = rt_stm32_eth_init; + stm32_eth_device.parent.parent.open = rt_stm32_eth_open; + stm32_eth_device.parent.parent.close = rt_stm32_eth_close; + stm32_eth_device.parent.parent.read = rt_stm32_eth_read; + stm32_eth_device.parent.parent.write = rt_stm32_eth_write; + stm32_eth_device.parent.parent.control = rt_stm32_eth_control; + stm32_eth_device.parent.parent.user_data = RT_NULL; + + stm32_eth_device.parent.eth_rx = rt_stm32_eth_rx; + stm32_eth_device.parent.eth_tx = rt_stm32_eth_tx; + + STM32_ETH_PRINTF("sem init: tx_wait\r\n"); + /* init tx semaphore */ + rt_sem_init(&tx_wait, "tx_wait", 0, RT_IPC_FLAG_FIFO); + + /* register eth device */ + STM32_ETH_PRINTF("eth_device_init start\r\n"); + state = eth_device_init(&(stm32_eth_device.parent), "e0"); + if (RT_EOK == state) + { + STM32_ETH_PRINTF("eth_device_init success\r\n"); + } + else + { + STM32_ETH_PRINTF("eth_device_init faild: %d\r\n", state); + } + return state; +} +INIT_DEVICE_EXPORT(rt_hw_stm32_eth_init); diff --git a/bsp/stm32f429-apollo/drivers/drv_eth.h b/bsp/stm32f429-apollo/drivers/drv_eth.h new file mode 100644 index 0000000000..b309ba00c1 --- /dev/null +++ b/bsp/stm32f429-apollo/drivers/drv_eth.h @@ -0,0 +1,6 @@ +#ifndef __DRV_ETH_H__ +#define __DRV_ETH_H__ + +void rt_hw_stm32_eth_init(void); + +#endif diff --git a/bsp/stm32f429-apollo/drivers/drv_iic.c b/bsp/stm32f429-apollo/drivers/drv_iic.c new file mode 100644 index 0000000000..fe50970c74 --- /dev/null +++ b/bsp/stm32f429-apollo/drivers/drv_iic.c @@ -0,0 +1,113 @@ +/* + * File : drv_iic.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2017 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-06-05 tanek first implementation. + */ + +#include "drv_iic.h" + +#include +#include +#include +#include + +#define DEBUG + +#ifdef DEBUG +#define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__) +#else +#define DEBUG_PRINTF(...) +#endif + +static void stm32f4_i2c_gpio_init() +{ + GPIO_InitTypeDef GPIO_Initure; + + __HAL_RCC_GPIOH_CLK_ENABLE(); + + GPIO_Initure.Pin = GPIO_PIN_4 | GPIO_PIN_5; + GPIO_Initure.Mode = GPIO_MODE_OUTPUT_OD; + GPIO_Initure.Pull = GPIO_PULLUP; + GPIO_Initure.Speed = GPIO_SPEED_FAST; + HAL_GPIO_Init(GPIOH, &GPIO_Initure); + + HAL_GPIO_WritePin(GPIOH, GPIO_PIN_5, GPIO_PIN_SET); + HAL_GPIO_WritePin(GPIOH, GPIO_PIN_4, GPIO_PIN_SET); +} + +static void stm32f4_set_sda(void *data, rt_int32_t state) +{ + HAL_GPIO_WritePin(GPIOH, GPIO_PIN_5, (GPIO_PinState)state); +} + +static void stm32f4_set_scl(void *data, rt_int32_t state) +{ + HAL_GPIO_WritePin(GPIOH, GPIO_PIN_4, (GPIO_PinState)state); +} + +static rt_int32_t stm32f4_get_sda(void *data) +{ + return (rt_int32_t)HAL_GPIO_ReadPin(GPIOH, GPIO_PIN_5); +} + +static rt_int32_t stm32f4_get_scl(void *data) +{ + return (rt_int32_t)HAL_GPIO_ReadPin(GPIOH, GPIO_PIN_4); +} + +static void stm32f4_udelay(rt_uint32_t us) +{ + rt_int32_t i; + for (; us > 0; us--) + { + i = 50; + while (i > 0) + { + i--; + } + } +} + +static const struct rt_i2c_bit_ops bit_ops = { + RT_NULL, + stm32f4_set_sda, + stm32f4_set_scl, + stm32f4_get_sda, + stm32f4_get_scl, + + stm32f4_udelay, + + 5, + 100 +}; + +int stm32f4_i2c_init(void) +{ + struct rt_i2c_bus_device *bus; + + bus = rt_malloc(sizeof(struct rt_i2c_bus_device)); + if (bus == RT_NULL) + { + rt_kprintf("rt_malloc failed\n"); + return -RT_ENOMEM; + } + + rt_memset((void *)bus, 0, sizeof(struct rt_i2c_bus_device)); + + bus->priv = (void *)&bit_ops; + + stm32f4_i2c_gpio_init(); + + rt_i2c_bit_add_bus(bus, "i2c0"); + + return RT_EOK; +} +INIT_DEVICE_EXPORT(stm32f4_i2c_init); diff --git a/bsp/stm32f429-apollo/drivers/drv_iic.h b/bsp/stm32f429-apollo/drivers/drv_iic.h new file mode 100644 index 0000000000..f31890e989 --- /dev/null +++ b/bsp/stm32f429-apollo/drivers/drv_iic.h @@ -0,0 +1,24 @@ +/* +* File : drv_iic.c +* This file is part of RT-Thread RTOS +* COPYRIGHT (C) 2017 RT-Thread Develop Team +* +* The license and distribution terms for this file may be +* found in the file LICENSE in this distribution or at +* http://www.rt-thread.org/license/LICENSE +* +* Change Logs: +* Date Author Notes +* 2017-06-05 tanek first implementation. +*/ + +#ifndef STM32F4XX_IIC_INCLUDED +#define STM32F4XX_IIC_INCLUDED + +#include +#include + +#include "stm32f4xx_hal.h" + + +#endif // STM32F20X_40X_SPI_H_INCLUDED diff --git a/bsp/stm32f429-apollo/drivers/drv_lcd.c b/bsp/stm32f429-apollo/drivers/drv_lcd.c new file mode 100644 index 0000000000..21d1a0b0df --- /dev/null +++ b/bsp/stm32f429-apollo/drivers/drv_lcd.c @@ -0,0 +1,603 @@ +/* + * File : drv_lcd.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-06-08 tanek first implementation + */ + +#include "drv_lcd.h" +#include + +//#define DEBUG + +#ifdef DEBUG +#define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__) +#else +#define DEBUG_PRINTF(...) +#endif + +typedef struct +{ + rt_uint16_t width; //LCD 宽度 + rt_uint16_t height; //LCD 高度 + rt_uint16_t id; //LCD ID + rt_uint8_t dir; //横屏还是竖屏控制:0,竖屏;1,横屏。 + rt_uint16_t wramcmd; //开始写gram指令 + rt_uint16_t setxcmd; //设置x坐标指令 + rt_uint16_t setycmd; //设置y坐标指令 +} lcd_info_t; + +typedef struct +{ + volatile rt_uint16_t reg; + volatile rt_uint16_t ram; +} lcd_ili9341_t; + +//使用NOR/SRAM的 Bank1.sector1,地址位HADDR[27,26]=00 A18作为数据命令区分线 +//注意设置时STM32内部会右移一位对其! +#define LCD_ILI9341_BASE ((rt_uint32_t)(0x60000000 | 0x0007FFFE)) +#define ili9341 ((lcd_ili9341_t *) LCD_ILI9341_BASE) +////////////////////////////////////////////////////////////////////////////////// + +//扫描方向定义 +#define L2R_U2D 0 //从左到右,从上到下 +#define L2R_D2U 1 //从左到右,从下到上 +#define R2L_U2D 2 //从右到左,从上到下 +#define R2L_D2U 3 //从右到左,从下到上 +#define U2D_L2R 4 //从上到下,从左到右 +#define U2D_R2L 5 //从上到下,从右到左 +#define D2U_L2R 6 //从下到上,从左到右 +#define D2U_R2L 7 //从下到上,从右到左 +#define DFT_SCAN_DIR L2R_U2D //默认的扫描方向 + +static lcd_info_t lcddev; + +void delay_us(rt_uint32_t nus) +{ + //rt_thread_delay(1); + while (nus--) { + __NOP(); + } +} + +void delay_ms(rt_uint32_t nms) +{ + //rt_thread_delay((RT_TICK_PER_SECOND * nms + 999) / 1000); + while (nms--) + { + int i; + for (i = 0; i < 10000; i++) + { + __NOP(); + } + } +} + +static void ili9341_write_reg(rt_uint16_t regval) +{ + ili9341->reg = regval; +} + +static void ili9341_write_data(rt_uint16_t data) +{ + ili9341->ram = data; +} + +rt_uint16_t ili9341_read_ram(void) +{ + return ili9341->ram; +} + +static void ili9341_write_reg_with_value(rt_uint16_t reg, rt_uint16_t regValue) +{ + ili9341->reg = reg; + ili9341->ram = regValue; +} + +static void ili9341_write_ram_prepare(void) +{ + ili9341->reg = lcddev.wramcmd; +} + +rt_uint16_t ili9341_bgr2rgb(rt_uint16_t value) +{ + rt_uint16_t red, green, blue; + + blue = (value >> 0) & 0x1f; + green = (value >> 5) & 0x3f; + red = (value >> 11) & 0x1f; + + return (blue << 11) + (green << 5) + (red << 0); +} + +static void ili9341_set_cursor(rt_uint16_t Xpos, rt_uint16_t Ypos) +{ + ili9341_write_reg(lcddev.setxcmd); + ili9341_write_data(Xpos >> 8); + ili9341_write_data(Xpos & 0XFF); + + ili9341_write_reg(lcddev.setycmd); + ili9341_write_data(Ypos >> 8); + ili9341_write_data(Ypos & 0XFF); +} + +static void ili9341_set_scan_direction(rt_uint8_t dir) +{ + rt_uint16_t regval = 0; + rt_uint16_t dirreg = 0; + rt_uint16_t temp; + + switch (dir) + { + case L2R_U2D://从左到右,从上到下 + regval |= (0 << 7) | (0 << 6) | (0 << 5); + break; + case L2R_D2U://从左到右,从下到上 + regval |= (1 << 7) | (0 << 6) | (0 << 5); + break; + case R2L_U2D://从右到左,从上到下 + regval |= (0 << 7) | (1 << 6) | (0 << 5); + break; + case R2L_D2U://从右到左,从下到上 + regval |= (1 << 7) | (1 << 6) | (0 << 5); + break; + case U2D_L2R://从上到下,从左到右 + regval |= (0 << 7) | (0 << 6) | (1 << 5); + break; + case U2D_R2L://从上到下,从右到左 + regval |= (0 << 7) | (1 << 6) | (1 << 5); + break; + case D2U_L2R://从下到上,从左到右 + regval |= (1 << 7) | (0 << 6) | (1 << 5); + break; + case D2U_R2L://从下到上,从右到左 + regval |= (1 << 7) | (1 << 6) | (1 << 5); + break; + } + + dirreg = 0X36; + ili9341_write_reg_with_value(dirreg, regval); + + if (regval & 0X20) + { + if (lcddev.width < lcddev.height)//交换X,Y + { + temp = lcddev.width; + lcddev.width = lcddev.height; + lcddev.height = temp; + } + } + else + { + if (lcddev.width > lcddev.height)//交换X,Y + { + temp = lcddev.width; + lcddev.width = lcddev.height; + lcddev.height = temp; + } + } + + ili9341_write_reg(lcddev.setxcmd); + ili9341_write_data(0); + ili9341_write_data(0); + ili9341_write_data((lcddev.width - 1) >> 8); + ili9341_write_data((lcddev.width - 1) & 0XFF); + + ili9341_write_reg(lcddev.setycmd); + ili9341_write_data(0); + ili9341_write_data(0); + ili9341_write_data((lcddev.height - 1) >> 8); + ili9341_write_data((lcddev.height - 1) & 0XFF); +} + +void ili9341_set_backlight(rt_uint8_t pwm) +{ + ili9341_write_reg(0xBE); + ili9341_write_data(0x05); + ili9341_write_data(pwm*2.55); + ili9341_write_data(0x01); + ili9341_write_data(0xFF); + ili9341_write_data(0x00); + ili9341_write_data(0x00); +} + +void ili9341_set_display_direction(rt_uint8_t dir) +{ + lcddev.dir = dir; + if (dir == 0) + { + lcddev.width = 240; + lcddev.height = 320; + } + else + { + lcddev.width = 320; + lcddev.height = 240; + } + + lcddev.wramcmd = 0X2C; + lcddev.setxcmd = 0X2A; + lcddev.setycmd = 0X2B; + + ili9341_set_scan_direction(DFT_SCAN_DIR); +} + +void HAL_SRAM_MspInit(SRAM_HandleTypeDef *hsram) +{ + GPIO_InitTypeDef GPIO_Initure; + + __HAL_RCC_FMC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_GPIOE_CLK_ENABLE(); + + //init PD0,1,4,5,7,8,9,10,13,14,15 + GPIO_Initure.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_7 | GPIO_PIN_8 | \ + GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; + GPIO_Initure.Mode = GPIO_MODE_AF_PP; + GPIO_Initure.Pull = GPIO_PULLUP; + GPIO_Initure.Speed = GPIO_SPEED_HIGH; + GPIO_Initure.Alternate = GPIO_AF12_FMC; + HAL_GPIO_Init(GPIOD, &GPIO_Initure); + + //init PE7,8,9,10,11,12,13,14,15 + GPIO_Initure.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | \ + GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; + HAL_GPIO_Init(GPIOE, &GPIO_Initure); +} + +SRAM_HandleTypeDef SRAM_Handler; + +void _lcd_low_level_init(void) +{ + GPIO_InitTypeDef GPIO_Initure; + + FMC_NORSRAM_TimingTypeDef FMC_ReadWriteTim; + FMC_NORSRAM_TimingTypeDef FMC_WriteTim; + + __HAL_RCC_GPIOB_CLK_ENABLE(); + GPIO_Initure.Pin = GPIO_PIN_5; + GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_Initure.Pull = GPIO_PULLUP; + GPIO_Initure.Speed = GPIO_SPEED_HIGH; + HAL_GPIO_Init(GPIOB, &GPIO_Initure); + + SRAM_Handler.Instance = FMC_NORSRAM_DEVICE; + SRAM_Handler.Extended = FMC_NORSRAM_EXTENDED_DEVICE; + + SRAM_Handler.Init.NSBank = FMC_NORSRAM_BANK1; + SRAM_Handler.Init.DataAddressMux = FMC_DATA_ADDRESS_MUX_DISABLE; + SRAM_Handler.Init.MemoryType = FMC_MEMORY_TYPE_SRAM; + SRAM_Handler.Init.MemoryDataWidth = FMC_NORSRAM_MEM_BUS_WIDTH_16; + SRAM_Handler.Init.BurstAccessMode = FMC_BURST_ACCESS_MODE_DISABLE; + SRAM_Handler.Init.WaitSignalPolarity = FMC_WAIT_SIGNAL_POLARITY_LOW; + SRAM_Handler.Init.WaitSignalActive = FMC_WAIT_TIMING_BEFORE_WS; + SRAM_Handler.Init.WriteOperation = FMC_WRITE_OPERATION_ENABLE; + SRAM_Handler.Init.WaitSignal = FMC_WAIT_SIGNAL_DISABLE; + SRAM_Handler.Init.ExtendedMode = FMC_EXTENDED_MODE_ENABLE; + SRAM_Handler.Init.AsynchronousWait = FMC_ASYNCHRONOUS_WAIT_DISABLE; + SRAM_Handler.Init.WriteBurst = FMC_WRITE_BURST_DISABLE; + SRAM_Handler.Init.ContinuousClock = FMC_CONTINUOUS_CLOCK_SYNC_ASYNC; + + FMC_ReadWriteTim.AddressSetupTime = 0x0F; + FMC_ReadWriteTim.AddressHoldTime = 0x00; + FMC_ReadWriteTim.DataSetupTime = 0x46; + FMC_ReadWriteTim.AccessMode = FMC_ACCESS_MODE_A; + + FMC_WriteTim.AddressSetupTime = 0x0F; + FMC_WriteTim.AddressHoldTime = 0x00; + FMC_WriteTim.DataSetupTime = 0x0F; + FMC_WriteTim.AccessMode = FMC_ACCESS_MODE_A; + HAL_SRAM_Init(&SRAM_Handler, &FMC_ReadWriteTim, &FMC_WriteTim); + delay_ms(50); + + ili9341_write_reg(0XD3); + lcddev.id = ili9341_read_ram(); + lcddev.id = ili9341_read_ram(); + lcddev.id = ili9341_read_ram(); + lcddev.id <<= 8; + lcddev.id |= ili9341_read_ram(); + + DEBUG_PRINTF(" LCD ID:%x\r\n", lcddev.id); //打印LCD ID + + ili9341_write_reg(0xCF); + ili9341_write_data(0x00); + ili9341_write_data(0xC1); + ili9341_write_data(0X30); + ili9341_write_reg(0xED); + ili9341_write_data(0x64); + ili9341_write_data(0x03); + ili9341_write_data(0X12); + ili9341_write_data(0X81); + ili9341_write_reg(0xE8); + ili9341_write_data(0x85); + ili9341_write_data(0x10); + ili9341_write_data(0x7A); + ili9341_write_reg(0xCB); + ili9341_write_data(0x39); + ili9341_write_data(0x2C); + ili9341_write_data(0x00); + ili9341_write_data(0x34); + ili9341_write_data(0x02); + ili9341_write_reg(0xF7); + ili9341_write_data(0x20); + ili9341_write_reg(0xEA); + ili9341_write_data(0x00); + ili9341_write_data(0x00); + ili9341_write_reg(0xC0); //Power control + ili9341_write_data(0x1B); //VRH[5:0] + ili9341_write_reg(0xC1); //Power control + ili9341_write_data(0x01); //SAP[2:0];BT[3:0] + ili9341_write_reg(0xC5); //VCM control + ili9341_write_data(0x30); //3F + ili9341_write_data(0x30); //3C + ili9341_write_reg(0xC7); //VCM control2 + ili9341_write_data(0XB7); + ili9341_write_reg(0x36); // memory access control + ili9341_write_data(0x08); // change here + ili9341_write_reg(0x3A); + ili9341_write_data(0x55); + ili9341_write_reg(0xB1); + ili9341_write_data(0x00); + ili9341_write_data(0x1A); + ili9341_write_reg(0xB6); //display function control + ili9341_write_data(0x0A); + ili9341_write_data(0xA2); + ili9341_write_reg(0xF2); //3gamma function disable + ili9341_write_data(0x00); + ili9341_write_reg(0x26); //gamma curve selected + ili9341_write_data(0x01); + ili9341_write_reg(0xE0); //set gamma + ili9341_write_data(0x0F); + ili9341_write_data(0x2A); + ili9341_write_data(0x28); + ili9341_write_data(0x08); + ili9341_write_data(0x0E); + ili9341_write_data(0x08); + ili9341_write_data(0x54); + ili9341_write_data(0XA9); + ili9341_write_data(0x43); + ili9341_write_data(0x0A); + ili9341_write_data(0x0F); + ili9341_write_data(0x00); + ili9341_write_data(0x00); + ili9341_write_data(0x00); + ili9341_write_data(0x00); + ili9341_write_reg(0XE1); //set gamma + ili9341_write_data(0x00); + ili9341_write_data(0x15); + ili9341_write_data(0x17); + ili9341_write_data(0x07); + ili9341_write_data(0x11); + ili9341_write_data(0x06); + ili9341_write_data(0x2B); + ili9341_write_data(0x56); + ili9341_write_data(0x3C); + ili9341_write_data(0x05); + ili9341_write_data(0x10); + ili9341_write_data(0x0F); + ili9341_write_data(0x3F); + ili9341_write_data(0x3F); + ili9341_write_data(0x0F); + ili9341_write_reg(0x2B); + ili9341_write_data(0x00); + ili9341_write_data(0x00); + ili9341_write_data(0x01); + ili9341_write_data(0x3f); + ili9341_write_reg(0x2A); + ili9341_write_data(0x00); + ili9341_write_data(0x00); + ili9341_write_data(0x00); + ili9341_write_data(0xef); + ili9341_write_reg(0x11); //exit sleep + delay_ms(120); + ili9341_write_reg(0x29); //display on + + FMC_Bank1E->BWTR[0] &= ~(0XF << 0); + FMC_Bank1E->BWTR[0] &= ~(0XF << 8); + FMC_Bank1E->BWTR[0] |= 4 << 0; + FMC_Bank1E->BWTR[0] |= 4 << 8; + + ili9341_set_display_direction(0); + HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET); +} + + +static rt_err_t lcd_init(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_err_t lcd_open(rt_device_t dev, rt_uint16_t oflag) +{ + return RT_EOK; +} + +static rt_err_t lcd_close(rt_device_t dev) +{ + return RT_EOK; +} + +static rt_err_t lcd_control(rt_device_t dev, rt_uint8_t cmd, void *args) +{ + switch (cmd) + { + case RTGRAPHIC_CTRL_GET_INFO: + { + struct rt_device_graphic_info *info; + + info = (struct rt_device_graphic_info*) args; + RT_ASSERT(info != RT_NULL); + + info->bits_per_pixel = 16; + info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565; + info->framebuffer = RT_NULL; + info->width = 240; + info->height = 320; + } + break; + + case RTGRAPHIC_CTRL_RECT_UPDATE: + /* nothong to be done */ + break; + + default: + break; + } + + return RT_EOK; +} + +static void ili9341_lcd_set_pixel(const char* pixel, int x, int y) +{ + ili9341_set_cursor(x, y); + ili9341_write_ram_prepare(); + ili9341->ram = *(uint16_t *)pixel; +} +#ifdef RT_USING_FINSH +static void lcd_set_pixel(uint16_t color, int x, int y) +{ + rt_kprintf("lcd set pixel, color: %X, x: %d, y: %d", color, x, y); + ili9341_lcd_set_pixel((const char *)&color, x, y); +} +FINSH_FUNCTION_EXPORT(lcd_set_pixel, set pixel in lcd display); +#endif + +static void ili9341_lcd_get_pixel(char* pixel, int x, int y) +{ + rt_uint16_t red = 0; + rt_uint16_t green = 0; + rt_uint16_t blue = 0; + + if (x >= lcddev.width || y >= lcddev.height) + { + *(rt_uint16_t*)pixel = 0; + return; + } + + ili9341_set_cursor(x, y); + + ili9341_write_reg(0X2E); + ili9341_read_ram(); + red = ili9341_read_ram(); + delay_us(2); + + blue = ili9341_read_ram(); + green = red & 0XFF; + + *(rt_uint16_t*)pixel = (((red >> 11) << 11) | ((green >> 10) << 5) | (blue >> 11)); +} +#ifdef RT_USING_FINSH +static void lcd_get_pixel(int x, int y) +{ + uint16_t pixel; + ili9341_lcd_get_pixel((char *)&pixel, x, y); + rt_kprintf("lcd get pixel, pixel: 0x%X, x: %d, y: %d", pixel, x, y); +} +FINSH_FUNCTION_EXPORT(lcd_get_pixel, get pixel in lcd display); +#endif + +static void ili9341_lcd_draw_hline(const char* pixel, int x1, int x2, int y) +{ + ili9341_set_cursor(x1, y); + ili9341_write_ram_prepare(); + + for (; x1 < x2; x1++) + { + ili9341->ram = *(uint16_t *)pixel; + } +} +#ifdef RT_USING_FINSH +static void lcd_draw_hline(uint16_t pixel, int x1, int x2, int y) +{ + ili9341_lcd_draw_hline((const char *)&pixel, x1, x2, y); + rt_kprintf("lcd draw hline, pixel: 0x%X, x1: %d, x2: %d, y: %d", pixel, x1, x2, y); +} +FINSH_FUNCTION_EXPORT(lcd_draw_hline, draw hline in lcd display); +#endif + +static void ili9341_lcd_draw_vline(const char* pixel, int x, int y1, int y2) +{ + for (; y1 < y2; y1++) + { + ili9341_lcd_set_pixel(pixel, x, y1); //write red data + } +} +#ifdef RT_USING_FINSH +static void lcd_draw_vline(uint16_t pixel, int x, int y1, int y2) +{ + ili9341_lcd_draw_vline((const char *)&pixel, x, y1, y2); + rt_kprintf("lcd draw hline, pixel: 0x%X, x: %d, y: %d", pixel, y1, y2); +} +FINSH_FUNCTION_EXPORT(lcd_draw_vline, draw vline in lcd display); +#endif + +static void ili9341_lcd_blit_line(const char* pixels, int x, int y, rt_size_t size) +{ + rt_uint16_t *ptr = (rt_uint16_t*)pixels; + + ili9341_set_cursor(x, y); + ili9341_write_ram_prepare(); + + while (size--) + { + ili9341->ram = *ptr++; + } +} +#ifdef RT_USING_FINSH +#define LINE_LEN 30 +static void lcd_blit_line(int x, int y) +{ + uint16_t pixels[LINE_LEN]; + int i; + + for (i = 0; i < LINE_LEN; i++) + { + pixels[i] = i * 40 + 50; + } + + ili9341_lcd_blit_line((const char *)pixels, x, y, LINE_LEN); + rt_kprintf("lcd blit line, x: %d, y: %d", x, y); +} +FINSH_FUNCTION_EXPORT(lcd_blit_line, draw blit line in lcd display); +#endif + +static int rt_hw_lcd_init(void) +{ + _lcd_low_level_init(); + + static struct rt_device lcd_device; + + static struct rt_device_graphic_ops ili9341_ops = + { + ili9341_lcd_set_pixel, + ili9341_lcd_get_pixel, + ili9341_lcd_draw_hline, + ili9341_lcd_draw_vline, + ili9341_lcd_blit_line + }; + + /* register lcd device */ + lcd_device.type = RT_Device_Class_Graphic; + lcd_device.init = lcd_init; + lcd_device.open = lcd_open; + lcd_device.close = lcd_close; + lcd_device.control = lcd_control; + lcd_device.read = RT_NULL; + lcd_device.write = RT_NULL; + + lcd_device.user_data = &ili9341_ops; + + /* register graphic device driver */ + rt_device_register(&lcd_device, "lcd", + RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE); + + return 0; +} +INIT_BOARD_EXPORT(rt_hw_lcd_init); diff --git a/bsp/stm32f429-apollo/drivers/drv_lcd.h b/bsp/stm32f429-apollo/drivers/drv_lcd.h new file mode 100644 index 0000000000..9247b0a91c --- /dev/null +++ b/bsp/stm32f429-apollo/drivers/drv_lcd.h @@ -0,0 +1,14 @@ +#ifndef __DRV_LCD_H__ +#define __DRV_LCD_H__ + +#include +#include "stm32f4xx_hal.h" + +int rt_lcd_init(void); + +#endif + + + + + diff --git a/bsp/stm32f429-apollo/drivers/drv_pcf8574.c b/bsp/stm32f429-apollo/drivers/drv_pcf8574.c new file mode 100644 index 0000000000..4801a92bc2 --- /dev/null +++ b/bsp/stm32f429-apollo/drivers/drv_pcf8574.c @@ -0,0 +1,100 @@ +/* + * File : drv_iic.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2017 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-06-09 tanek first implementation. + */ +#include "drv_pcf8574.h" +#include +#include +#include + +//#define DEBUG + +#ifdef DEBUG +#define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__) +#else +#define DEBUG_PRINTF(...) +#endif + +#define I2C_BUS_NAME "i2c0" +#define PCF8574_ADDR 0x20 + +static uint8_t rt_pcf8574_read_onebyte(void); +static void rt_pcf8574_write_onebyte(rt_uint8_t value); + +static struct rt_i2c_bus_device * i2c_bus; + +rt_err_t rt_pcf8574_init(void) +{ + rt_uint8_t buffer[] = { 0xFF }; + rt_off_t pos = PCF8574_ADDR; + + __HAL_RCC_GPIOB_CLK_ENABLE(); + + i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(I2C_BUS_NAME); + if (i2c_bus == RT_NULL) + { + DEBUG_PRINTF("\ni2c_bus %s for PCF8574 not found!\n", I2C_BUS_NAME); + return -RT_ENOSYS; + } + + if (rt_device_open(&i2c_bus->parent, RT_NULL) != RT_EOK) + { + DEBUG_PRINTF("\ni2c_bus %s for cs43l22 opened failed!\n", I2C_BUS_NAME); + return -RT_EEMPTY; + } + + rt_device_write(&i2c_bus->parent, pos, &buffer, 1); + + return RT_EOK; +} + +static uint8_t rt_pcf8574_read_onebyte(void) +{ + rt_uint8_t value; + + rt_device_read(&i2c_bus->parent, PCF8574_ADDR, &value, 1); + + return value; +} + + +static void rt_pcf8574_write_onebyte(rt_uint8_t value) +{ + rt_device_write(&i2c_bus->parent, PCF8574_ADDR, &value, 1); +} + + +void rt_pcf8574_write_bit(rt_uint8_t bit, rt_uint8_t state) +{ + rt_uint8_t data; + data = rt_pcf8574_read_onebyte(); + + if (state == 0) + data &= ~(1 << bit); + else + data |= 1 << bit; + + rt_pcf8574_write_onebyte(data); +} + + +rt_uint8_t rt_pcf8574_read_bit(rt_uint8_t bit) +{ + rt_uint8_t data; + data = rt_pcf8574_read_onebyte(); + + if (data&(1 << bit)) + return 1; + else + return 0; +} + diff --git a/bsp/stm32f429-apollo/drivers/drv_pcf8574.h b/bsp/stm32f429-apollo/drivers/drv_pcf8574.h new file mode 100644 index 0000000000..8940982c26 --- /dev/null +++ b/bsp/stm32f429-apollo/drivers/drv_pcf8574.h @@ -0,0 +1,25 @@ +#ifndef __DRV_PCF8574_H +#define __DRV_PCF8574_H + +#include +#include +#include +#include + +//PCF8574各个IO的功能 +#define BEEP_IO 0 //蜂鸣器控制引脚 P0 +#define AP_INT_IO 1 //AP3216C中断引脚 P1 +#define DCMI_PWDN_IO 2 //DCMI的电源控制引脚 P2 +#define USB_PWR_IO 3 //USB电源控制引脚 P3 +#define EX_IO 4 //扩展IO,自定义使用 P4 +#define MPU_INT_IO 5 //MPU9250中断引脚 P5 +#define RS485_RE_IO 6 //RS485_RE引脚 P6 +#define ETH_RESET_IO 7 //以太网复位引脚 P7 + +rt_err_t rt_pcf8574_init(void); + +void rt_pcf8574_write_bit(rt_uint8_t bit, rt_uint8_t state); +rt_uint8_t rt_pcf8574_read_bit(rt_uint8_t bit); + +#endif + diff --git a/bsp/stm32f429-apollo/drivers/drv_spi.c b/bsp/stm32f429-apollo/drivers/drv_spi.c new file mode 100644 index 0000000000..c249a0c82f --- /dev/null +++ b/bsp/stm32f429-apollo/drivers/drv_spi.c @@ -0,0 +1,734 @@ +/* + * File : drv_spi.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2017 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2017-06-05 tanek first implementation. + */ + +#include "drv_spi.h" + +#include +#include + +//#define DEBUG + +#ifdef DEBUG +#define DEBUG_PRINTF(...) rt_kprintf(__VA_ARGS__) +#else +#define DEBUG_PRINTF(...) +#endif + +/* private rt-thread spi ops function */ +static rt_err_t configure(struct rt_spi_device* device, struct rt_spi_configuration* configuration); +static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message); + +static struct rt_spi_ops stm32_spi_ops = +{ + configure, + xfer +}; + +#ifdef SPI_USE_DMA +static uint8_t dummy = 0xFF; +static void DMA_RxConfiguration(struct rt_spi_bus * spi_bus, + struct rt_spi_message* message) +{ + struct stm32f4_spi *f4_spi = (struct stm32f4_spi *)spi_bus->parent.user_data; + + DMA_HandleTypeDef * hdma_tx = &f4_spi->hdma_tx; + DMA_HandleTypeDef * hdma_rx = &f4_spi->hdma_rx; + + HAL_DMA_DeInit(hdma_tx); + HAL_DMA_DeInit(hdma_rx); + + /* Check if the DMA Stream is disabled before enabling it. + Note that this step is useful when the same Stream is used multiple times: + enabled, then disabled then re-enabled... In this case, the DMA Stream disable + will be effective only at the end of the ongoing data transfer and it will + not be possible to re-configure it before making sure that the Enable bit + has been cleared by hardware. If the Stream is used only once, this step might + be bypassed. */ + while (hdma_tx->Instance->CR & DMA_SxCR_EN); + while (hdma_rx->Instance->CR & DMA_SxCR_EN); + + if(message->recv_buf != RT_NULL) + { + hdma_rx->Init.MemInc = DMA_MINC_ENABLE; + } + else + { + message->recv_buf = &dummy; + hdma_rx->Init.MemInc = DMA_MINC_DISABLE; + } + HAL_DMA_Init(hdma_rx); + + __HAL_LINKDMA(&f4_spi->spi_handle, hdmarx, f4_spi->hdma_rx); + + if(message->send_buf != RT_NULL) + { + hdma_tx->Init.MemInc = DMA_MINC_ENABLE; + } + else + { + dummy = 0xFF; + message->send_buf = &dummy; + hdma_tx->Init.MemInc = DMA_MINC_DISABLE; + } + HAL_DMA_Init(hdma_tx); + + __HAL_LINKDMA(&f4_spi->spi_handle, hdmatx, f4_spi->hdma_tx); + + /* NVIC configuration for DMA transfer complete interrupt*/ + HAL_NVIC_SetPriority(f4_spi->hdma_tx_irq, 0, 1); + HAL_NVIC_EnableIRQ(f4_spi->hdma_tx_irq); + + /* NVIC configuration for DMA transfer complete interrupt*/ + HAL_NVIC_SetPriority(f4_spi->hdma_rx_irq, 0, 0); + HAL_NVIC_EnableIRQ(f4_spi->hdma_rx_irq); + +} +#endif + +static rt_err_t configure(struct rt_spi_device* device, + struct rt_spi_configuration* configuration) +{ + struct rt_spi_bus * spi_bus = (struct rt_spi_bus *)device->bus; + struct stm32f4_spi *f4_spi = (struct stm32f4_spi *)spi_bus->parent.user_data; + SPI_HandleTypeDef * SpiHandle = &f4_spi->spi_handle; + + RT_ASSERT(device != RT_NULL); + RT_ASSERT(configuration != RT_NULL); + + /* data_width */ + if(configuration->data_width <= 8) + { + SpiHandle->Init.DataSize = SPI_DATASIZE_8BIT; + } + else if(configuration->data_width <= 16) + { + SpiHandle->Init.DataSize = SPI_DATASIZE_16BIT; + } + else + { + return RT_EIO; + } + + /* baudrate */ + { + uint32_t SPI_APB_CLOCK; + uint32_t max_hz; + + max_hz = configuration->max_hz; + + DEBUG_PRINTF("sys freq: %d\n", HAL_RCC_GetSysClockFreq()); + DEBUG_PRINTF("pclk2 freq: %d\n", HAL_RCC_GetPCLK2Freq()); + + SPI_APB_CLOCK = HAL_RCC_GetPCLK2Freq(); + + if(max_hz >= SPI_APB_CLOCK/2) + { + SpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_2; + } + else if(max_hz >= SPI_APB_CLOCK/4) + { + SpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4; + } + else if(max_hz >= SPI_APB_CLOCK/8) + { + SpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_8; + } + else if(max_hz >= SPI_APB_CLOCK/16) + { + SpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_16; + } + else if(max_hz >= SPI_APB_CLOCK/32) + { + SpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32; + } + else if(max_hz >= SPI_APB_CLOCK/64) + { + SpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_64; + } + else if(max_hz >= SPI_APB_CLOCK/128) + { + SpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_128; + } + else + { + /* min prescaler 256 */ + SpiHandle->Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_256; + } + } /* baudrate */ + + /* CPOL */ + if(configuration->mode & RT_SPI_CPOL) + { + SpiHandle->Init.CLKPolarity = SPI_POLARITY_HIGH; + } + else + { + SpiHandle->Init.CLKPolarity = SPI_POLARITY_LOW; + } + /* CPHA */ + if(configuration->mode & RT_SPI_CPHA) + { + SpiHandle->Init.CLKPhase = SPI_PHASE_2EDGE; + } + else + { + SpiHandle->Init.CLKPhase = SPI_PHASE_1EDGE; + } + /* MSB or LSB */ + if(configuration->mode & RT_SPI_MSB) + { + SpiHandle->Init.FirstBit = SPI_FIRSTBIT_MSB; + } + else + { + SpiHandle->Init.FirstBit = SPI_FIRSTBIT_LSB; + } + SpiHandle->Init.Direction = SPI_DIRECTION_2LINES; + SpiHandle->Init.Mode = SPI_MODE_MASTER; + SpiHandle->Init.NSS = SPI_NSS_SOFT; + SpiHandle->Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE; + SpiHandle->Init.TIMode = SPI_TIMODE_DISABLE; + + /* init SPI */ + if (HAL_SPI_Init(SpiHandle) != HAL_OK) + { + return RT_ERROR; + } + /* Enable SPI_MASTER */ + __HAL_SPI_ENABLE(SpiHandle); + + DEBUG_PRINTF("spi configuration\n"); + + return RT_EOK; +}; + +static rt_uint32_t xfer(struct rt_spi_device* device, struct rt_spi_message* message) +{ + struct rt_spi_bus * stm32_spi_bus = (struct rt_spi_bus *)device->bus; + struct stm32f4_spi *f4_spi = (struct stm32f4_spi *)stm32_spi_bus->parent.user_data; + struct rt_spi_configuration * config = &device->config; + SPI_TypeDef * SPI = f4_spi->spi_handle.Instance; + struct stm32_spi_cs * stm32_spi_cs = device->parent.user_data; + rt_uint32_t size = message->length; + + RT_ASSERT(device != NULL); + RT_ASSERT(message != NULL); + + /* take CS */ + if(message->cs_take) + { + HAL_GPIO_WritePin(stm32_spi_cs->GPIOx, stm32_spi_cs->GPIO_Pin, GPIO_PIN_RESET); + } + +#ifdef SPI_USE_DMA + if(message->length > 32) + { + if(config->data_width <= 8) + { + HAL_StatusTypeDef state; + DEBUG_PRINTF("spi dma transfer start\n"); + DMA_RxConfiguration(stm32_spi_bus, message); + DEBUG_PRINTF("dma configuration finish , send buf %X, rec buf %X, length: %d\n", + (uint32_t)message->send_buf, (uint32_t)message->recv_buf, message->length); + + state = HAL_SPI_TransmitReceive_DMA(&f4_spi->spi_handle, + (uint8_t*)message->send_buf, + (uint8_t*)message->recv_buf, + message->length); + if (state != HAL_OK) + { + DEBUG_PRINTF("spi flash configuration error : %d\n", state); + message->length = 0; + //while(1); + } + else + { + DEBUG_PRINTF("spi dma transfer finish\n"); + } + + while (HAL_SPI_GetState(&f4_spi->spi_handle) != HAL_SPI_STATE_READY); + DEBUG_PRINTF("spi get state finish\n"); + } + else + { + // Todo + } + } + else +#endif + { + if(config->data_width <= 8) + { + const rt_uint8_t * send_ptr = message->send_buf; + rt_uint8_t * recv_ptr = message->recv_buf; + + while(size--) + { + rt_uint8_t data = 0xFF; + + if(send_ptr != RT_NULL) + { + data = *send_ptr++; + } + + // Todo: replace register read/write by stm32f4 lib + //Wait until the transmit buffer is empty + while ((SPI->SR & SPI_FLAG_TXE) == RESET); + // Send the byte + SPI->DR = data; + + //Wait until a data is received + while ((SPI->SR & SPI_FLAG_RXNE) == RESET); + // Get the received data + data = SPI->DR; + + if(recv_ptr != RT_NULL) + { + *recv_ptr++ = data; + } + } + } + else if(config->data_width <= 16) + { + const rt_uint16_t * send_ptr = message->send_buf; + rt_uint16_t * recv_ptr = message->recv_buf; + + while(size--) + { + rt_uint16_t data = 0xFF; + + if(send_ptr != RT_NULL) + { + data = *send_ptr++; + } + + //Wait until the transmit buffer is empty + while ((SPI->SR & SPI_FLAG_TXE) == RESET); + // Send the byte + SPI->DR = data; + + //Wait until a data is received + while ((SPI->SR & SPI_FLAG_RXNE) == RESET); + // Get the received data + data = SPI->DR; + + if(recv_ptr != RT_NULL) + { + *recv_ptr++ = data; + } + } + } + } + + /* release CS */ + if(message->cs_release) + { + //GPIO_SetBits(stm32_spi_cs->GPIOx, stm32_spi_cs->GPIO_Pin); + HAL_GPIO_WritePin(stm32_spi_cs->GPIOx, stm32_spi_cs->GPIO_Pin, GPIO_PIN_SET); + } + + return message->length; +}; + + + + + +#ifdef RT_USING_SPI1 + +static struct stm32f4_spi stm32f4_spi1 = +{ + /* .spi_handle = */{ + /* .Instance = */ SPI1, + }, + /* .hdma_rx = */ { + DMA2_Stream2, + DMA_CHANNEL_3, + }, + /* .hdma_rx_irq = */ DMA2_Stream2_IRQn, + + /* .hdma_tx = */{ + DMA2_Stream3, + DMA_CHANNEL_3, + }, + /* .hdma_tx_irq = */ DMA2_Stream3_IRQn, +}; + +static struct rt_spi_bus spi1_bus; + +/** + * @brief This function handles DMA Rx interrupt request. + * @param None + * @retval None + */ +void DMA2_Stream2_IRQHandler(void) +{ + HAL_DMA_IRQHandler(stm32f4_spi1.spi_handle.hdmarx); +} +/** + * @brief This function handles DMA Tx interrupt request. + * @param None + * @retval None + */ +void DMA2_Stream3_IRQHandler(void) +{ + HAL_DMA_IRQHandler(stm32f4_spi1.spi_handle.hdmatx); +} + +#endif + +#ifdef RT_USING_SPI2 + +struct stm32f4_spi stm32f4_spi2 = +{ + /* .spi_handle = */{ + /* .Instance = */ SPI2, + }, + /* .hdma_rx = */ { + DMA1_Stream3, + DMA_CHANNEL_0, + }, + /* .hdma_rx_irq = */ DMA1_Stream3_IRQn, + + /* .hdma_tx = */{ + DMA1_Stream4, + DMA_CHANNEL_0, + }, + /* .hdma_tx_irq = */ DMA1_Stream4_IRQn, +}; + +static struct rt_spi_bus spi2_bus; + +/** + * @brief This function handles DMA Rx interrupt request. + * @param None + * @retval None + */ +void DMA1_Stream3_IRQHandler(void) +{ + HAL_DMA_IRQHandler(stm32f4_spi2.spi_handle.hdmarx); +} +/** + * @brief This function handles DMA Tx interrupt request. + * @param None + * @retval None + */ +void DMA1_Stream4_IRQHandler(void) +{ + HAL_DMA_IRQHandler(stm32f4_spi2.spi_handle.hdmatx); +} + +#endif + +#ifdef RT_USING_SPI3 + +struct stm32f4_spi stm32f4_spi3 = +{ + /* .spi_handle = */{ + /* .Instance = */ SPI3, + }, + /* .hdma_rx = */ { + DMA1_Stream0, + DMA_CHANNEL_0, + }, + /* .hdma_rx_irq = */ DMA1_Stream0_IRQn, + + /* .hdma_tx = */{ + DMA1_Stream2, + DMA_CHANNEL_0, + }, + /* .hdma_tx_irq = */ DMA1_Stream2_IRQn, +}; + +static struct rt_spi_bus spi3_bus; + + +/** + * @brief This function handles DMA Rx interrupt request. + * @param None + * @retval None + */ +void DMA1_Stream0_IRQHandler(void) +{ + HAL_DMA_IRQHandler(stm32f4_spi3.spi_handle.hdmarx); +} +/** + * @brief This function handles DMA Tx interrupt request. + * @param None + * @retval None + */ +void DMA1_Stream2_IRQHandler(void) +{ + HAL_DMA_IRQHandler(stm32f4_spi3.spi_handle.hdmatx); +} + +#endif + +#ifdef RT_USING_SPI4 + +struct stm32f4_spi stm32f4_spi4 = +{ + /* .spi_handle = */{ + /* .Instance = */ SPI5, + }, + /* .hdma_rx = */ { + DMA2_Stream0, + DMA_CHANNEL_4, + }, + /* .hdma_rx_irq = */ DMA2_Stream0_IRQn, + + /* .hdma_tx = */{ + DMA2_Stream1, + DMA_CHANNEL_4, + }, + /* .hdma_tx_irq = */ DMA2_Stream1_IRQn, +}; + +static struct rt_spi_bus spi4_bus; + + +/** + * @brief This function handles DMA Rx interrupt request. + * @param None + * @retval None + */ +void DMA2_Stream0_IRQHandler(void) +{ + HAL_DMA_IRQHandler(stm32f4_spi4.spi_handle.hdmarx); +} +/** + * @brief This function handles DMA Tx interrupt request. + * @param None + * @retval None + */ +void DMA2_Stream1_IRQHandler(void) +{ + HAL_DMA_IRQHandler(stm32f4_spi4.spi_handle.hdmatx); +} + +#endif + +#ifdef RT_USING_SPI5 + +struct stm32f4_spi stm32f4_spi5 = +{ + /* .spi_handle = */{ + /* .Instance = */ SPI5, + }, + /* .hdma_rx = */ { + DMA2_Stream3, + DMA_CHANNEL_2, + }, + /* .hdma_rx_irq = */ DMA2_Stream3_IRQn, + + /* .hdma_tx = */{ + DMA2_Stream4, + DMA_CHANNEL_2, + }, + /* .hdma_tx_irq = */ DMA2_Stream4_IRQn, +}; + +static struct rt_spi_bus spi5_bus; + + +/** + * @brief This function handles DMA Rx interrupt request. + * @param None + * @retval None + */ +void DMA2_Stream3_IRQHandler(void) +{ + HAL_DMA_IRQHandler(stm32f4_spi5.spi_handle.hdmarx); +} +/** + * @brief This function handles DMA Tx interrupt request. + * @param None + * @retval None + */ +void DMA2_Stream4_IRQHandler(void) +{ + HAL_DMA_IRQHandler(stm32f4_spi5.spi_handle.hdmatx); +} + +#endif + +#ifdef RT_USING_SPI6 + +struct stm32f4_spi stm32f4_spi6 = +{ + /* .spi_handle = */{ + /* .Instance = */ SPI5, + }, + /* .hdma_rx = */ { + DMA2_Stream6, + DMA_CHANNEL_2, + }, + /* .hdma_rx_irq = */ DMA2_Stream6_IRQn, + + /* .hdma_tx = */{ + DMA2_Stream5, + DMA_CHANNEL_2, + }, + /* .hdma_tx_irq = */ DMA2_Stream5_IRQn, +}; + +static struct rt_spi_bus spi6_bus; + + +/** + * @brief This function handles DMA Rx interrupt request. + * @param None + * @retval None + */ +void DMA2_Stream6_IRQHandler(void) +{ + HAL_DMA_IRQHandler(stm32f4_spi6.spi_handle.hdmarx); +} +/** + * @brief This function handles DMA Tx interrupt request. + * @param None + * @retval None + */ +void DMA2_Stream5_IRQHandler(void) +{ + HAL_DMA_IRQHandler(stm32f4_spi6.spi_handle.hdmatx); +} + +#endif + +/** \brief init and register stm32 spi bus. + * + * \param SPI: STM32 SPI, e.g: SPI1,SPI2,SPI3. + * \param spi_bus_name: spi bus name, e.g: "spi1" + * \return + * + */ +rt_err_t stm32_spi_bus_register(SPI_TypeDef * SPI, + //struct stm32_spi_bus * stm32_spi, + const char * spi_bus_name) +{ + struct stm32f4_spi * p_spi_bus; + struct rt_spi_bus * spi_bus; + + RT_ASSERT(SPI != RT_NULL); + //RT_ASSERT(stm32_spi != RT_NULL); + RT_ASSERT(spi_bus_name != RT_NULL); + +#ifdef RT_USING_SPI1 + if(SPI == SPI1) + { + #ifdef SPI_USE_DMA + __HAL_RCC_DMA2_CLK_ENABLE(); + p_spi_bus = &stm32f4_spi1; + #endif + __HAL_RCC_SPI1_CLK_ENABLE(); + spi_bus = &spi1_bus; + } +#endif + +#ifdef RT_USING_SPI2 + if(SPI == SPI2) + { + #ifdef SPI_USE_DMA + __HAL_RCC_DMA1_CLK_ENABLE(); + p_spi_bus = &stm32f4_spi2; + #endif + __HAL_RCC_SPI2_CLK_ENABLE(); + spi_bus = &spi2_bus; + } +#endif + +#ifdef RT_USING_SPI3 + if(SPI == SPI3) + { + //stm32_spi->spi_handle.Instance = SPI3; + #ifdef SPI_USE_DMA + __HAL_RCC_DMA1_CLK_ENABLE(); + p_spi_bus = &stm32f4_spi3; + #endif + __HAL_RCC_SPI3_CLK_ENABLE(); + spi_bus = &spi3_bus; + } +#endif + +#ifdef RT_USING_SPI4 + if(SPI == SPI4) + { +#ifdef SPI_USE_DMA + __HAL_RCC_DMA2_CLK_ENABLE(); +#endif + __HAL_RCC_SPI4_CLK_ENABLE(); + spi_bus = &spi4_bus; + } +#endif + +#ifdef RT_USING_SPI5 + if(SPI == SPI5) + { + #ifdef SPI_USE_DMA + __HAL_RCC_DMA2_CLK_ENABLE(); + p_spi_bus = &stm32f4_spi5; + #endif + __HAL_RCC_SPI5_CLK_ENABLE(); + spi_bus = &spi5_bus; + } +#endif + +#ifdef RT_USING_SPI6 + if(SPI == SPI6) + { + #ifdef SPI_USE_DMA + __HAL_RCC_DMA2_CLK_ENABLE(); + p_spi_bus = &stm32f4_spi5; + #endif + __HAL_RCC_SPI6_CLK_ENABLE(); + spi_bus = &spi6_bus; + } +#endif + + if ( (SPI != SPI1) && (SPI != SPI2) && (SPI != SPI3) + && (SPI != SPI4) && (SPI != SPI5) && (SPI != SPI6)) + { + return RT_ENOSYS; + } + + /* Configure the DMA handler for Transmission process */ + p_spi_bus->hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; + p_spi_bus->hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE; + //p_spi_bus->hdma_tx.Init.MemInc = DMA_MINC_ENABLE; + p_spi_bus->hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + p_spi_bus->hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + p_spi_bus->hdma_tx.Init.Mode = DMA_NORMAL; + p_spi_bus->hdma_tx.Init.Priority = DMA_PRIORITY_LOW; + p_spi_bus->hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + p_spi_bus->hdma_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + p_spi_bus->hdma_tx.Init.MemBurst = DMA_MBURST_INC4; + p_spi_bus->hdma_tx.Init.PeriphBurst = DMA_PBURST_INC4; + + p_spi_bus->hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; + p_spi_bus->hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE; + //p_spi_bus->hdma_rx.Init.MemInc = DMA_MINC_ENABLE; + p_spi_bus->hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; + p_spi_bus->hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; + p_spi_bus->hdma_rx.Init.Mode = DMA_NORMAL; + p_spi_bus->hdma_rx.Init.Priority = DMA_PRIORITY_HIGH; + p_spi_bus->hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; + p_spi_bus->hdma_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; + p_spi_bus->hdma_rx.Init.MemBurst = DMA_MBURST_INC4; + p_spi_bus->hdma_rx.Init.PeriphBurst = DMA_PBURST_INC4; + + spi_bus->parent.user_data = &stm32f4_spi5; + + return rt_spi_bus_register(spi_bus, spi_bus_name, &stm32_spi_ops); +} diff --git a/bsp/stm32f429-apollo/drivers/drv_spi.h b/bsp/stm32f429-apollo/drivers/drv_spi.h new file mode 100644 index 0000000000..8967b4b981 --- /dev/null +++ b/bsp/stm32f429-apollo/drivers/drv_spi.h @@ -0,0 +1,49 @@ +/* + * File : stm32f20x_40x_spi.h + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 20012-01-01 aozima first implementation. + */ + +#ifndef STM32F20X_40X_SPI_H_INCLUDED +#define STM32F20X_40X_SPI_H_INCLUDED + +#include +#include + +#include "stm32f4xx_hal.h" + +#define SPI_USE_DMA + +struct stm32f4_spi +{ + SPI_HandleTypeDef spi_handle; +#ifdef SPI_USE_DMA + DMA_HandleTypeDef hdma_rx; + IRQn_Type hdma_rx_irq; + + DMA_HandleTypeDef hdma_tx; + IRQn_Type hdma_tx_irq; +#endif /* #ifdef SPI_USE_DMA */ +}; + + +struct stm32_spi_cs +{ + GPIO_TypeDef * GPIOx; + uint16_t GPIO_Pin; +}; + +/* public function */ +rt_err_t stm32_spi_bus_register(SPI_TypeDef * SPI, + //struct stm32_spi_bus * stm32_spi, + const char * spi_bus_name); + +#endif // STM32F20X_40X_SPI_H_INCLUDED diff --git a/bsp/stm32f429-apollo/drivers/drv_spi_flash.c b/bsp/stm32f429-apollo/drivers/drv_spi_flash.c new file mode 100644 index 0000000000..d570e7d602 --- /dev/null +++ b/bsp/stm32f429-apollo/drivers/drv_spi_flash.c @@ -0,0 +1,87 @@ +/* + * File : stm32f20x_40x_spi.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2009 RT-Thread Develop Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2012-01-01 aozima first implementation. + * 2012-07-27 aozima fixed variable uninitialized. + */ +#include +#include "drv_spi.h" +#include "spi_flash.h" +#include "spi_flash_sfud.h" + +#include +#include + + +static int rt_hw_spi5_init(void) +{ + /* register spi bus */ + { + GPIO_InitTypeDef GPIO_InitStructure; + rt_err_t result; + + __HAL_RCC_GPIOF_CLK_ENABLE(); + + GPIO_InitStructure.Alternate = GPIO_AF5_SPI5; + GPIO_InitStructure.Mode = GPIO_MODE_AF_PP; + GPIO_InitStructure.Pull = GPIO_PULLUP; + GPIO_InitStructure.Speed = GPIO_SPEED_FAST; + GPIO_InitStructure.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9; + HAL_GPIO_Init(GPIOF, &GPIO_InitStructure); + + result = stm32_spi_bus_register(SPI5, "spi5"); + if (result != RT_EOK) + { + return result; + } + } + + /* attach cs */ + { + static struct rt_spi_device spi_device; + static struct stm32_spi_cs spi_cs; + rt_err_t result; + + GPIO_InitTypeDef GPIO_InitStructure; + + GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP; + GPIO_InitStructure.Pull = GPIO_PULLUP; + GPIO_InitStructure.Speed = GPIO_SPEED_FAST; + + spi_cs.GPIOx = GPIOF; + spi_cs.GPIO_Pin = GPIO_PIN_6; + //__HAL_RCC_GPIOF_CLK_ENABLE(); + + GPIO_InitStructure.Pin = spi_cs.GPIO_Pin; + HAL_GPIO_WritePin(spi_cs.GPIOx, spi_cs.GPIO_Pin, GPIO_PIN_SET); + HAL_GPIO_Init(spi_cs.GPIOx, &GPIO_InitStructure); + + result = rt_spi_bus_attach_device(&spi_device, "spi50", "spi5", (void*)&spi_cs); + if (result != RT_EOK) + { + return result; + } + } + + return RT_EOK; +} +INIT_DEVICE_EXPORT(rt_hw_spi5_init); + +static int rt_hw_spi_flash_with_sfud_init(void) +{ + if (RT_NULL == rt_sfud_flash_probe("W25Q256", "spi50")) + { + return RT_ERROR; + }; + + return RT_EOK; +} +INIT_COMPONENT_EXPORT(rt_hw_spi_flash_with_sfud_init) diff --git a/bsp/stm32f429-apollo/drivers/stm32f4xx_hal_conf.h b/bsp/stm32f429-apollo/drivers/stm32f4xx_hal_conf.h index c2b889a958..a7633ed68a 100644 --- a/bsp/stm32f429-apollo/drivers/stm32f4xx_hal_conf.h +++ b/bsp/stm32f429-apollo/drivers/stm32f4xx_hal_conf.h @@ -58,11 +58,11 @@ /* #define HAL_DAC_MODULE_ENABLED */ /* #define HAL_DCMI_MODULE_ENABLED */ /* #define HAL_DMA2D_MODULE_ENABLED */ -/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_ETH_MODULE_ENABLED #define HAL_NAND_MODULE_ENABLED /* #define HAL_NOR_MODULE_ENABLED */ /* #define HAL_PCCARD_MODULE_ENABLED */ -/* #define HAL_SRAM_MODULE_ENABLED */ +#define HAL_SRAM_MODULE_ENABLED #define HAL_SDRAM_MODULE_ENABLED /* #define HAL_HASH_MODULE_ENABLED */ /* #define HAL_I2C_MODULE_ENABLED */ @@ -73,7 +73,7 @@ #define HAL_RTC_MODULE_ENABLED /* */ /* #define HAL_SAI_MODULE_ENABLED */ #define HAL_SD_MODULE_ENABLED /* */ -/* #define HAL_SPI_MODULE_ENABLED */ +#define HAL_SPI_MODULE_ENABLED /* #define HAL_TIM_MODULE_ENABLED */ #define HAL_UART_MODULE_ENABLED #define HAL_USART_MODULE_ENABLED diff --git a/bsp/stm32f429-apollo/rtconfig.h b/bsp/stm32f429-apollo/rtconfig.h index 9cae871999..09392f9060 100644 --- a/bsp/stm32f429-apollo/rtconfig.h +++ b/bsp/stm32f429-apollo/rtconfig.h @@ -66,6 +66,29 @@ #define RT_USING_DEVICE #define RT_USING_DEVICE_IPC +/* SECTION: RTGUI support */ +/* using RTGUI support */ +#define RT_USING_GUIENGINE + +/* name length of RTGUI object */ +#define RTGUI_NAME_MAX 16 +/* support 16 weight font */ +#define RTGUI_USING_FONT16 +/* support 16 weight font */ +#define RTGUI_USING_FONT12 +/* support Chinese font */ +#define RTGUI_USING_FONTHZ +/* use DFS as file interface */ +#define RTGUI_USING_DFS_FILERW +/* use font file as Chinese font */ +/* #define RTGUI_USING_HZ_FILE */ +/* use Chinese bitmap font */ +#define RTGUI_USING_HZ_BMP +/* use small size in RTGUI */ +/* #define RTGUI_USING_SMALL_SIZE */ +/* use mouse cursor */ +/* #define RTGUI_USING_MOUSE_CURSOR */ + /* Using serial framework */ #define RT_USING_SERIAL @@ -135,7 +158,7 @@ #define RT_DFS_ELM_CODE_PAGE 437 #define RT_DFS_ELM_MAX_LFN 255 /* Maximum sector size to be handled. */ -#define RT_DFS_ELM_MAX_SECTOR_SIZE 512 +#define RT_DFS_ELM_MAX_SECTOR_SIZE 4096 /* DFS: UFFS nand file system options */ @@ -151,7 +174,7 @@ // #define RT_USING_DFS_ROMFS /* SECTION: lwip, a lighwight TCP/IP protocol stack */ -/* #define RT_USING_LWIP */ +#define RT_USING_LWIP /* LwIP uses RT-Thread Memory Management */ #define RT_LWIP_USING_RT_MEM /* Enable ICMP protocol*/ @@ -162,6 +185,10 @@ #define RT_LWIP_TCP /* Enable DNS */ #define RT_LWIP_DNS +/* Enable DHCP */ +#define RT_LWIP_DHCP +/* Enable DEBUG */ +//#define RT_LWIP_DEBUG /* the number of simulatenously active TCP connections*/ #define RT_LWIP_TCP_PCB_NUM 5 @@ -203,11 +230,25 @@ #define CHECKSUM_CHECK_IP 0 #define CHECKSUM_CHECK_UDP 0 -#define CHECKSUM_GEN_TCP 0 -#define CHECKSUM_GEN_IP 0 -#define CHECKSUM_GEN_UDP 0 +//#define CHECKSUM_GEN_TCP 0 +//#define CHECKSUM_GEN_IP 0 +//#define CHECKSUM_GEN_UDP 0 /* RT_GDB_STUB */ //#define RT_USING_GDB +/* spi driver */ +#define RT_USING_SPI +#define RT_USING_SPI5 + +/* Serial Flash Universal Driver */ +#define RT_USING_SFUD +/* Enable SFUD debug output */ +//#define RT_DEBUG_SFUD 1 +/* serial flash discoverable parameters by JEDEC standard */ +#define RT_SFUD_USING_SFDP + +#define RT_USING_I2C +#define RT_USING_I2C_BITOPS + #endif