diff --git a/IoTGateWay/bsp/stm32/stm32f105RC/application/config/appconfig.h b/IoTGateWay/bsp/stm32/stm32f105RC/application/config/appconfig.h index 0dd0ce5134a49..89b05981e9829 100644 --- a/IoTGateWay/bsp/stm32/stm32f105RC/application/config/appconfig.h +++ b/IoTGateWay/bsp/stm32/stm32f105RC/application/config/appconfig.h @@ -50,7 +50,7 @@ #define DEFAULT_IP "0.0.0.0" #define DEFAULT_MAC "00:00:00:00:00:00" #define DEFAULT_DEVICE "TS0000" //Default Device Info -#define DEFAULT_DOMAIN "iot.espressif.cn" +#define DEFAULT_DOMAIN "onsite-monitor.xip.kr" #endif /* __APPCONFIG_H__ */ diff --git a/IoTGateWay/bsp/stm32/stm32f105RC/application/config/configuration.c b/IoTGateWay/bsp/stm32/stm32f105RC/application/config/configuration.c index 8ffb880283f57..f5729aec89d6b 100644 --- a/IoTGateWay/bsp/stm32/stm32f105RC/application/config/configuration.c +++ b/IoTGateWay/bsp/stm32/stm32f105RC/application/config/configuration.c @@ -141,7 +141,7 @@ void SetApPassword(rt_uint8_t *pData, rt_size_t dataSize) if(0 != rt_strncmp((char *)pCfg->networkdCofig.apPassword, (char *)pData, dataSize)) { - rt_memset(pCfg->networkdCofig.apPassword,0,AP_MAX_LENGTH); + rt_memset(pCfg->networkdCofig.apPassword,0,AP_MAX_PASSWORD_LENGTH); rt_memcpy(pCfg->networkdCofig.apPassword,pData,dataSize); rt_kprintf("Set Ap Password: %s\r\n", pCfg->networkdCofig.apPassword); FlashWrite((rt_uint8_t *)pCfg, sizeof(Config)); @@ -159,7 +159,7 @@ void SetApSSID(rt_uint8_t *pData, rt_size_t dataSize) if(0 != rt_strncmp((char *)pCfg->networkdCofig.apSSID, (char *)pData, dataSize)) { - rt_memset(pCfg->networkdCofig.apSSID,0,AP_MAX_LENGTH); + rt_memset(pCfg->networkdCofig.apSSID,0,AP_MAX_SSID_LENGTH); rt_memcpy(pCfg->networkdCofig.apSSID,pData,dataSize); rt_kprintf("Set Ap SSID: %s\r\n", pCfg->networkdCofig.apSSID); FlashWrite((rt_uint8_t *)pCfg, sizeof(Config)); @@ -216,7 +216,7 @@ void SetDeviceInfo(rt_uint8_t *pData, rt_size_t dataSize) if(0 != rt_strncmp((char *)pCfg->device, (char *)pData, dataSize)) { - rt_memset(pCfg->device,0,dataSize); + rt_memset(pCfg->device,0,sizeof(pCfg->device)); rt_memcpy(pCfg->device,pData,dataSize); rt_kprintf("Set Device Info: %s\r\n", pCfg->device); FlashWrite((rt_uint8_t *)pCfg, sizeof(Config)); @@ -271,7 +271,7 @@ void SetDomainInfo(rt_uint8_t *pData, rt_size_t dataSize) if(0 != rt_strncmp((char *)pCfg->networkdCofig.domainInfo, (char *)pData, dataSize)) { - rt_memset(pCfg->networkdCofig.domainInfo,0,dataSize); + rt_memset(pCfg->networkdCofig.domainInfo,0,MAX_DOMAIN_LENGTH); rt_memcpy(pCfg->networkdCofig.domainInfo,pData,dataSize); rt_kprintf("Set Domain Info: %s\r\n", pCfg->networkdCofig.domainInfo); FlashWrite((rt_uint8_t *)pCfg, sizeof(Config)); @@ -308,13 +308,14 @@ rt_bool_t LoadConfig(void) if(RT_FALSE == retVal || WATERMARK_VALUE != pCfg->waterMark) { rt_kprintf("Set Factory Reset...\r\n"); + rt_memset(pCfg,0,sizeof(Config)); pCfg->networkdCofig.destPort = 0; pCfg->networkdCofig.dhcpMode = 1; pCfg->networkdCofig.domainOn = DISABLE; pCfg->waterMark = WATERMARK_VALUE; pCfg->manufacture = DISABLE; - rt_memcpy(pCfg->networkdCofig.apSSID,DEFAULT_IP,rt_strlen(DEFAULT_SSID)); - rt_memcpy(pCfg->networkdCofig.apPassword,DEFAULT_IP,rt_strlen(DEFAULT_PASSWORD)); + rt_memcpy(pCfg->networkdCofig.apSSID,DEFAULT_SSID,rt_strlen(DEFAULT_SSID)); + rt_memcpy(pCfg->networkdCofig.apPassword,DEFAULT_PASSWORD,rt_strlen(DEFAULT_PASSWORD)); rt_memcpy(pCfg->networkdCofig.destIp,DEFAULT_IP,rt_strlen(DEFAULT_IP)); rt_memcpy(pCfg->networkdCofig.dnsServer,DEFAULT_IP,rt_strlen(DEFAULT_IP)); rt_memcpy(pCfg->networkdCofig.gatewayIp,DEFAULT_IP,rt_strlen(DEFAULT_IP)); diff --git a/IoTGateWay/bsp/stm32/stm32f105RC/application/config/configuration.h b/IoTGateWay/bsp/stm32/stm32f105RC/application/config/configuration.h index 685482663f4bd..83f1bb86f3538 100644 --- a/IoTGateWay/bsp/stm32/stm32f105RC/application/config/configuration.h +++ b/IoTGateWay/bsp/stm32/stm32f105RC/application/config/configuration.h @@ -8,15 +8,16 @@ #ifndef __CONFIGURATION_H__ #define __CONFIGURATION_H__ -#define AP_MAX_LENGTH 32 +#define AP_MAX_SSID_LENGTH 32 +#define AP_MAX_PASSWORD_LENGTH 64 #define IP_MAX_LENGTH 16 #define MAC_LENGTH 18 #define MAX_DOMAIN_LENGTH 64 #pragma pack(push, 1) typedef struct _NetworkdCofig{ - rt_uint8_t apSSID[AP_MAX_LENGTH]; - rt_uint8_t apPassword[AP_MAX_LENGTH]; + rt_uint8_t apSSID[AP_MAX_SSID_LENGTH]; + rt_uint8_t apPassword[AP_MAX_PASSWORD_LENGTH]; rt_uint8_t destIp[IP_MAX_LENGTH]; rt_uint16_t destPort; diff --git a/IoTGateWay/bsp/stm32/stm32f105RC/application/network/wifi/wifi.c b/IoTGateWay/bsp/stm32/stm32f105RC/application/network/wifi/wifi.c index b7b0df1a9596c..0ec4ff835fe06 100644 --- a/IoTGateWay/bsp/stm32/stm32f105RC/application/network/wifi/wifi.c +++ b/IoTGateWay/bsp/stm32/stm32f105RC/application/network/wifi/wifi.c @@ -78,12 +78,12 @@ typedef struct _WifiInfo rt_uint8_t dhcp; //Wi-Fi Info - rt_uint8_t ssid[64]; - rt_uint8_t password[64]; + rt_uint8_t ssid[AP_MAX_SSID_LENGTH<<1]; + rt_uint8_t password[AP_MAX_PASSWORD_LENGTH<<1]; //TCP Info rt_uint8_t domainConfig; - rt_uint8_t remoteIp[16]; + rt_uint8_t remoteIp[IP_MAX_LENGTH]; rt_uint16_t remotePort; rt_uint8_t domain[WIFI_MAX_LEN]; @@ -151,7 +151,7 @@ rt_uint8_t *MakeWifiFormat(rt_uint8_t *pData) { end = pos++; } - else + else if(0x80 > *pos) { rt_uint8_t buf[64]; end = pos; @@ -591,12 +591,12 @@ void InitWifInformation(void) wifiInfo.mode = 1; //Station wifiInfo.dhcp = GetDhcpMode(); - rt_uint8_t ssid[64]; - rt_uint8_t password[64]; - rt_memcpy(ssid,GetApSSID(),WIFI_MAX_LEN); - rt_memcpy(wifiInfo.ssid,MakeWifiFormat(ssid),WIFI_MAX_LEN); - rt_memcpy(password,GetApPassword(),WIFI_MAX_LEN); - rt_memcpy(wifiInfo.password,MakeWifiFormat(password),WIFI_MAX_LEN); + rt_uint8_t ssid[AP_MAX_SSID_LENGTH]; + rt_uint8_t password[AP_MAX_PASSWORD_LENGTH]; + rt_memcpy(ssid,GetApSSID(),AP_MAX_SSID_LENGTH); + rt_memcpy(wifiInfo.ssid,MakeWifiFormat(ssid),AP_MAX_SSID_LENGTH); + rt_memcpy(password,GetApPassword(),AP_MAX_PASSWORD_LENGTH); + rt_memcpy(wifiInfo.password,MakeWifiFormat(password),AP_MAX_PASSWORD_LENGTH); rt_memcpy(wifiInfo.remoteIp,GetTcpIp(),sizeof(wifiInfo.remoteIp)); rt_memcpy(wifiInfo.domain,GetDomainInfo(),sizeof(wifiInfo.domain)); diff --git a/IoTGateWay/components/drivers/spi/SConscript b/IoTGateWay/components/drivers/spi/SConscript deleted file mode 100644 index e19f30861fb9f..0000000000000 --- a/IoTGateWay/components/drivers/spi/SConscript +++ /dev/null @@ -1,37 +0,0 @@ -from building import * -import rtconfig - -cwd = GetCurrentDir() -src = ['spi_core.c', 'spi_dev.c'] -CPPPATH = [cwd, cwd + '/../include'] -LOCAL_CCFLAGS = '' - -if GetDepend('RT_USING_QSPI'): - src += ['qspi_core.c'] - -src_device = [] - -if GetDepend('RT_USING_SPI_WIFI'): - src_device += ['spi_wifi_rw009.c'] - -if GetDepend('RT_USING_ENC28J60'): - src_device += ['enc28j60.c'] - -if GetDepend('RT_USING_SPI_MSD'): - src_device += ['spi_msd.c'] - -if GetDepend('RT_USING_SFUD'): - src_device += ['spi_flash_sfud.c', 'sfud/src/sfud.c'] - CPPPATH += [cwd + '/sfud/inc'] - if GetDepend('RT_SFUD_USING_SFDP'): - src_device += ['sfud/src/sfud_sfdp.c'] - if rtconfig.CROSS_TOOL == 'gcc': - LOCAL_CCFLAGS += ' -std=c99' - elif rtconfig.CROSS_TOOL == 'keil': - LOCAL_CCFLAGS += ' --c99' - -src += src_device - -group = DefineGroup('DeviceDrivers', src, depend = ['RT_USING_SPI'], CPPPATH = CPPPATH, LOCAL_CCFLAGS = LOCAL_CCFLAGS) - -Return('group') diff --git a/IoTGateWay/components/drivers/spi/device_driver_list.txt b/IoTGateWay/components/drivers/spi/device_driver_list.txt deleted file mode 100644 index 939baa75313f8..0000000000000 --- a/IoTGateWay/components/drivers/spi/device_driver_list.txt +++ /dev/null @@ -1,9 +0,0 @@ -spi_wifi_rw009.c/spi_wifi_rw009.h -RW009 -http://www.rt-thread.com/ - -enc28j60.c/enc28j60.h -http://www.microchip.com/ - -spi_flash_sfud: Serial Flash Universal Driver -https://github.com/armink/SFUD \ No newline at end of file diff --git a/IoTGateWay/components/drivers/spi/enc28j60.c b/IoTGateWay/components/drivers/spi/enc28j60.c deleted file mode 100644 index a8bfe3a159d3c..0000000000000 --- a/IoTGateWay/components/drivers/spi/enc28j60.c +++ /dev/null @@ -1,899 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#include "enc28j60.h" - -/* #define NET_TRACE */ -/* #define ETH_RX_DUMP */ -/* #define ETH_TX_DUMP */ - -#ifdef NET_TRACE - #define NET_DEBUG rt_kprintf -#else - #define NET_DEBUG(...) -#endif /* #ifdef NET_TRACE */ - -struct enc28j60_tx_list_typedef -{ - struct enc28j60_tx_list_typedef *prev; - struct enc28j60_tx_list_typedef *next; - rt_uint32_t addr; /* pkt addr in buffer */ - rt_uint32_t len; /* pkt len */ - volatile rt_bool_t free; /* 0:busy, 1:free */ -}; -static struct enc28j60_tx_list_typedef enc28j60_tx_list[2]; -static volatile struct enc28j60_tx_list_typedef *tx_current; -static volatile struct enc28j60_tx_list_typedef *tx_ack; -static struct rt_event tx_event; - -/* private enc28j60 define */ -/* enc28j60 spi interface function */ -static uint8_t spi_read_op(struct rt_spi_device *spi_device, uint8_t op, uint8_t address); -static void spi_write_op(struct rt_spi_device *spi_device, uint8_t op, uint8_t address, uint8_t data); - -static uint8_t spi_read(struct rt_spi_device *spi_device, uint8_t address); -static void spi_write(struct rt_spi_device *spi_device, rt_uint8_t address, rt_uint8_t data); - -static void enc28j60_clkout(struct rt_spi_device *spi_device, rt_uint8_t clk); -static void enc28j60_set_bank(struct rt_spi_device *spi_device, uint8_t address); -static uint32_t enc28j60_interrupt_disable(struct rt_spi_device *spi_device); -static void enc28j60_interrupt_enable(struct rt_spi_device *spi_device, uint32_t level); - -static uint16_t enc28j60_phy_read(struct rt_spi_device *spi_device, rt_uint8_t address); -static void enc28j60_phy_write(struct rt_spi_device *spi_device, rt_uint8_t address, uint16_t data); -static rt_bool_t enc28j60_check_link_status(struct rt_spi_device *spi_device); - -#define enc28j60_lock(dev) rt_mutex_take(&((struct net_device*)dev)->lock, RT_WAITING_FOREVER); -#define enc28j60_unlock(dev) rt_mutex_release(&((struct net_device*)dev)->lock); - -static struct net_device enc28j60_dev; -static uint8_t Enc28j60Bank; -//struct rt_spi_device * spi_device; -static uint16_t NextPacketPtr; - -static void _delay_us(uint32_t us) -{ - volatile uint32_t len; - for (; us > 0; us --) - for (len = 0; len < 20; len++); -} - -/* enc28j60 spi interface function */ -static uint8_t spi_read_op(struct rt_spi_device *spi_device, uint8_t op, uint8_t address) -{ - uint8_t send_buffer[2]; - uint8_t recv_buffer[1]; - uint32_t send_size = 1; - - send_buffer[0] = op | (address & ADDR_MASK); - send_buffer[1] = 0xFF; - - /* do dummy read if needed (for mac and mii, see datasheet page 29). */ - if (address & 0x80) - { - send_size = 2; - } - - rt_spi_send_then_recv(spi_device, send_buffer, send_size, recv_buffer, 1); - return (recv_buffer[0]); -} - -static void spi_write_op(struct rt_spi_device *spi_device, uint8_t op, uint8_t address, uint8_t data) -{ - uint32_t level; - uint8_t buffer[2]; - - level = rt_hw_interrupt_disable(); - - buffer[0] = op | (address & ADDR_MASK); - buffer[1] = data; - rt_spi_send(spi_device, buffer, 2); - - rt_hw_interrupt_enable(level); -} - -/* enc28j60 function */ -static void enc28j60_clkout(struct rt_spi_device *spi_device, rt_uint8_t clk) -{ - /* setup clkout: 2 is 12.5MHz: */ - spi_write(spi_device, ECOCON, clk & 0x7); -} - -static void enc28j60_set_bank(struct rt_spi_device *spi_device, uint8_t address) -{ - /* set the bank (if needed) .*/ - if ((address & BANK_MASK) != Enc28j60Bank) - { - /* set the bank. */ - spi_write_op(spi_device, ENC28J60_BIT_FIELD_CLR, ECON1, (ECON1_BSEL1 | ECON1_BSEL0)); - spi_write_op(spi_device, ENC28J60_BIT_FIELD_SET, ECON1, (address & BANK_MASK) >> 5); - Enc28j60Bank = (address & BANK_MASK); - } -} - -static uint8_t spi_read(struct rt_spi_device *spi_device, uint8_t address) -{ - /* set the bank. */ - enc28j60_set_bank(spi_device, address); - /* do the read. */ - return spi_read_op(spi_device, ENC28J60_READ_CTRL_REG, address); -} - -static void spi_write(struct rt_spi_device *spi_device, rt_uint8_t address, rt_uint8_t data) -{ - /* set the bank. */ - enc28j60_set_bank(spi_device, address); - /* do the write. */ - spi_write_op(spi_device, ENC28J60_WRITE_CTRL_REG, address, data); -} - -static uint16_t enc28j60_phy_read(struct rt_spi_device *spi_device, rt_uint8_t address) -{ - uint16_t value; - - /* Set the right address and start the register read operation. */ - spi_write(spi_device, MIREGADR, address); - spi_write(spi_device, MICMD, MICMD_MIIRD); - - _delay_us(15); - - /* wait until the PHY read completes. */ - while (spi_read(spi_device, MISTAT) & MISTAT_BUSY); - - /* reset reading bit */ - spi_write(spi_device, MICMD, 0x00); - - value = spi_read(spi_device, MIRDL) | spi_read(spi_device, MIRDH) << 8; - - return (value); -} - -static void enc28j60_phy_write(struct rt_spi_device *spi_device, rt_uint8_t address, uint16_t data) -{ - /* set the PHY register address. */ - spi_write(spi_device, MIREGADR, address); - - /* write the PHY data. */ - spi_write(spi_device, MIWRL, data); - spi_write(spi_device, MIWRH, data >> 8); - - /* wait until the PHY write completes. */ - while (spi_read(spi_device, MISTAT) & MISTAT_BUSY) - { - _delay_us(15); - } -} - -static uint32_t enc28j60_interrupt_disable(struct rt_spi_device *spi_device) -{ - uint32_t level; - - /* switch to bank 0 */ - enc28j60_set_bank(spi_device, EIE); - - /* get last interrupt level */ - level = spi_read(spi_device, EIE); - /* disable interrutps */ - spi_write_op(spi_device, ENC28J60_BIT_FIELD_CLR, EIE, level); - - return level; -} - -static void enc28j60_interrupt_enable(struct rt_spi_device *spi_device, uint32_t level) -{ - /* switch to bank 0 */ - enc28j60_set_bank(spi_device, EIE); - spi_write_op(spi_device, ENC28J60_BIT_FIELD_SET, EIE, level); -} - -/* - * Access the PHY to determine link status - */ -static rt_bool_t enc28j60_check_link_status(struct rt_spi_device *spi_device) -{ - uint16_t reg; - - reg = enc28j60_phy_read(spi_device, PHSTAT2); - - if (reg & PHSTAT2_LSTAT) - { - /* on */ - return RT_TRUE; - } - else - { - /* off */ - return RT_FALSE; - } -} - -/************************* RT-Thread Device Interface *************************/ -void enc28j60_isr(void) -{ - eth_device_ready(&enc28j60_dev.parent); - NET_DEBUG("enc28j60_isr\r\n"); -} - -static void _tx_chain_init(void) -{ - enc28j60_tx_list[0].next = &enc28j60_tx_list[1]; - enc28j60_tx_list[1].next = &enc28j60_tx_list[0]; - - enc28j60_tx_list[0].prev = &enc28j60_tx_list[1]; - enc28j60_tx_list[1].prev = &enc28j60_tx_list[0]; - - enc28j60_tx_list[0].addr = TXSTART_INIT; - enc28j60_tx_list[1].addr = TXSTART_INIT + MAX_TX_PACKAGE_SIZE; - - enc28j60_tx_list[0].free = RT_TRUE; - enc28j60_tx_list[1].free = RT_TRUE; - - tx_current = &enc28j60_tx_list[0]; - tx_ack = tx_current; -} - -/* initialize the interface */ -static rt_err_t enc28j60_init(rt_device_t dev) -{ - struct net_device *enc28j60 = (struct net_device *)dev; - struct rt_spi_device *spi_device = enc28j60->spi_device; - - enc28j60_lock(dev); - - _tx_chain_init(); - - // perform system reset - spi_write_op(spi_device, ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET); - rt_thread_delay(RT_TICK_PER_SECOND / 50); /* delay 20ms */ - - NextPacketPtr = RXSTART_INIT; - - // Rx start - spi_write(spi_device, ERXSTL, RXSTART_INIT & 0xFF); - spi_write(spi_device, ERXSTH, RXSTART_INIT >> 8); - // set receive pointer address - spi_write(spi_device, ERXRDPTL, RXSTOP_INIT & 0xFF); - spi_write(spi_device, ERXRDPTH, RXSTOP_INIT >> 8); - // RX end - spi_write(spi_device, ERXNDL, RXSTOP_INIT & 0xFF); - spi_write(spi_device, ERXNDH, RXSTOP_INIT >> 8); - - // TX start - spi_write(spi_device, ETXSTL, TXSTART_INIT & 0xFF); - spi_write(spi_device, ETXSTH, TXSTART_INIT >> 8); - // set transmission pointer address - spi_write(spi_device, EWRPTL, TXSTART_INIT & 0xFF); - spi_write(spi_device, EWRPTH, TXSTART_INIT >> 8); - // TX end - spi_write(spi_device, ETXNDL, TXSTOP_INIT & 0xFF); - spi_write(spi_device, ETXNDH, TXSTOP_INIT >> 8); - - // do bank 1 stuff, packet filter: - // For broadcast packets we allow only ARP packtets - // All other packets should be unicast only for our mac (MAADR) - // - // The pattern to match on is therefore - // Type ETH.DST - // ARP BROADCAST - // 06 08 -- ff ff ff ff ff ff -> ip checksum for theses bytes=f7f9 - // in binary these poitions are:11 0000 0011 1111 - // This is hex 303F->EPMM0=0x3f,EPMM1=0x30 - spi_write(spi_device, ERXFCON, ERXFCON_UCEN | ERXFCON_CRCEN | ERXFCON_BCEN); - - // do bank 2 stuff - // enable MAC receive - spi_write(spi_device, MACON1, MACON1_MARXEN | MACON1_TXPAUS | MACON1_RXPAUS); - // enable automatic padding to 60bytes and CRC operations - // spi_write_op(ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0|MACON3_TXCRCEN|MACON3_FRMLNEN); - spi_write_op(spi_device, ENC28J60_BIT_FIELD_SET, MACON3, MACON3_PADCFG0 | MACON3_TXCRCEN | MACON3_FRMLNEN | MACON3_FULDPX); - // bring MAC out of reset - - // set inter-frame gap (back-to-back) - // spi_write(MABBIPG, 0x12); - spi_write(spi_device, MABBIPG, 0x15); - - spi_write(spi_device, MACON4, MACON4_DEFER); - spi_write(spi_device, MACLCON2, 63); - - // set inter-frame gap (non-back-to-back) - spi_write(spi_device, MAIPGL, 0x12); - spi_write(spi_device, MAIPGH, 0x0C); - - // Set the maximum packet size which the controller will accept - // Do not send packets longer than MAX_FRAMELEN: - spi_write(spi_device, MAMXFLL, MAX_FRAMELEN & 0xFF); - spi_write(spi_device, MAMXFLH, MAX_FRAMELEN >> 8); - - // do bank 3 stuff - // write MAC address - // NOTE: MAC address in ENC28J60 is byte-backward - spi_write(spi_device, MAADR0, enc28j60->dev_addr[5]); - spi_write(spi_device, MAADR1, enc28j60->dev_addr[4]); - spi_write(spi_device, MAADR2, enc28j60->dev_addr[3]); - spi_write(spi_device, MAADR3, enc28j60->dev_addr[2]); - spi_write(spi_device, MAADR4, enc28j60->dev_addr[1]); - spi_write(spi_device, MAADR5, enc28j60->dev_addr[0]); - - /* output off */ - spi_write(spi_device, ECOCON, 0x00); - - // enc28j60_phy_write(PHCON1, 0x00); - enc28j60_phy_write(spi_device, PHCON1, PHCON1_PDPXMD); // full duplex - // no loopback of transmitted frames - enc28j60_phy_write(spi_device, PHCON2, PHCON2_HDLDIS); - /* enable PHY link changed interrupt. */ - enc28j60_phy_write(spi_device, PHIE, PHIE_PGEIE | PHIE_PLNKIE); - - enc28j60_set_bank(spi_device, ECON2); - spi_write_op(spi_device, ENC28J60_BIT_FIELD_SET, ECON2, ECON2_AUTOINC); - - // switch to bank 0 - enc28j60_set_bank(spi_device, ECON1); - // enable all interrutps - spi_write_op(spi_device, ENC28J60_BIT_FIELD_SET, EIE, 0xFF); - // enable packet reception - spi_write_op(spi_device, ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); - - /* clock out */ - enc28j60_clkout(spi_device, 2); - - enc28j60_phy_write(spi_device, PHLCON, 0xD76); //0x476 - rt_thread_delay(RT_TICK_PER_SECOND / 50); /* delay 20ms */ - - enc28j60_unlock(dev); - return RT_EOK; -} - -/* control the interface */ -static rt_err_t enc28j60_control(rt_device_t dev, int cmd, void *args) -{ - struct net_device *enc28j60 = (struct net_device *)dev; - switch (cmd) - { - case NIOCTL_GADDR: - /* get mac address */ - if (args) rt_memcpy(args, enc28j60->dev_addr, 6); - else return -RT_ERROR; - break; - - default : - break; - } - - return RT_EOK; -} - -/* Open the ethernet interface */ -static rt_err_t enc28j60_open(rt_device_t dev, uint16_t oflag) -{ - return RT_EOK; -} - -/* Close the interface */ -static rt_err_t enc28j60_close(rt_device_t dev) -{ - return RT_EOK; -} - -/* Read */ -static rt_size_t enc28j60_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) -{ - rt_set_errno(-RT_ENOSYS); - return RT_EOK; -} - -/* Write */ -static rt_size_t enc28j60_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) -{ - rt_set_errno(-RT_ENOSYS); - return 0; -} - -/* ethernet device interface */ -/* Transmit packet. */ -static rt_err_t enc28j60_tx(rt_device_t dev, struct pbuf *p) -{ - struct net_device *enc28j60 = (struct net_device *)dev; - struct rt_spi_device *spi_device = enc28j60->spi_device; - struct pbuf *q; - rt_uint32_t level; -#ifdef ETH_TX_DUMP - rt_size_t dump_count = 0; - rt_uint8_t *dump_ptr; - rt_size_t dump_i; -#endif - - if (tx_current->free == RT_FALSE) - { - NET_DEBUG("[Tx] no empty buffer!\r\n"); - while (tx_current->free == RT_FALSE) - { - rt_err_t result; - rt_uint32_t recved; - - /* there is no block yet, wait a flag */ - result = rt_event_recv(&tx_event, 0x01, - RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, &recved); - - RT_ASSERT(result == RT_EOK); - } - NET_DEBUG("[Tx] wait empty buffer done!\r\n"); - } - - enc28j60_lock(dev); - - /* disable enc28j60 interrupt */ - level = enc28j60_interrupt_disable(spi_device); - - // Set the write pointer to start of transmit buffer area -// spi_write(EWRPTL, TXSTART_INIT&0xFF); -// spi_write(EWRPTH, TXSTART_INIT>>8); - spi_write(spi_device, EWRPTL, (tx_current->addr) & 0xFF); - spi_write(spi_device, EWRPTH, (tx_current->addr) >> 8); - // Set the TXND pointer to correspond to the packet size given - tx_current->len = p->tot_len; -// spi_write(ETXNDL, (TXSTART_INIT+ p->tot_len + 1)&0xFF); -// spi_write(ETXNDH, (TXSTART_INIT+ p->tot_len + 1)>>8); - - // write per-packet control byte (0x00 means use macon3 settings) - spi_write_op(spi_device, ENC28J60_WRITE_BUF_MEM, 0, 0x00); - -#ifdef ETH_TX_DUMP - NET_DEBUG("tx_dump, size:%d\r\n", p->tot_len); -#endif - for (q = p; q != NULL; q = q->next) - { - uint8_t cmd = ENC28J60_WRITE_BUF_MEM; - rt_spi_send_then_send(enc28j60->spi_device, &cmd, 1, q->payload, q->len); -#ifdef ETH_RX_DUMP - dump_ptr = q->payload; - for (dump_i = 0; dump_i < q->len; dump_i++) - { - NET_DEBUG("%02x ", *dump_ptr); - if (((dump_count + 1) % 8) == 0) - { - NET_DEBUG(" "); - } - if (((dump_count + 1) % 16) == 0) - { - NET_DEBUG("\r\n"); - } - dump_count++; - dump_ptr++; - } -#endif - } -#ifdef ETH_RX_DUMP - NET_DEBUG("\r\n"); -#endif - - // send the contents of the transmit buffer onto the network - if (tx_current == tx_ack) - { - NET_DEBUG("[Tx] stop, restart!\r\n"); - // TX start - spi_write(spi_device, ETXSTL, (tx_current->addr) & 0xFF); - spi_write(spi_device, ETXSTH, (tx_current->addr) >> 8); - // TX end - spi_write(spi_device, ETXNDL, (tx_current->addr + tx_current->len) & 0xFF); - spi_write(spi_device, ETXNDH, (tx_current->addr + tx_current->len) >> 8); - - spi_write_op(spi_device, ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); - } - else - { - NET_DEBUG("[Tx] busy, add to chain!\r\n"); - } - - tx_current->free = RT_FALSE; - tx_current = tx_current->next; - - /* Reset the transmit logic problem. See Rev. B4 Silicon Errata point 12. */ - if ((spi_read(spi_device, EIR) & EIR_TXERIF)) - { - spi_write_op(spi_device, ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST); - } - - /* enable enc28j60 interrupt */ - enc28j60_interrupt_enable(spi_device, level); - - enc28j60_unlock(dev); - - return RT_EOK; -} - -/* recv packet. */ -static struct pbuf *enc28j60_rx(rt_device_t dev) -{ - struct net_device *enc28j60 = (struct net_device *)dev; - struct rt_spi_device *spi_device = enc28j60->spi_device; - struct pbuf *p = RT_NULL; - - uint8_t eir, eir_clr; - uint32_t pk_counter; - rt_uint32_t level; - rt_uint32_t len; - rt_uint16_t rxstat; - - enc28j60_lock(dev); - - /* disable enc28j60 interrupt */ - level = enc28j60_interrupt_disable(spi_device); - - /* get EIR */ - eir = spi_read(spi_device, EIR); - - while (eir & ~EIR_PKTIF) - { - eir_clr = 0; - - /* clear PKTIF */ - if (eir & EIR_PKTIF) - { - NET_DEBUG("EIR_PKTIF\r\n"); - - /* switch to bank 0. */ - enc28j60_set_bank(spi_device, EIE); - /* disable rx interrutps. */ - spi_write_op(spi_device, ENC28J60_BIT_FIELD_CLR, EIE, EIE_PKTIE); - eir_clr |= EIR_PKTIF; -// enc28j60_set_bank(spi_device, EIR); -// spi_write_op(spi_device, ENC28J60_BIT_FIELD_CLR, EIR, EIR_PKTIF); - } - - /* clear DMAIF */ - if (eir & EIR_DMAIF) - { - NET_DEBUG("EIR_DMAIF\r\n"); - eir_clr |= EIR_DMAIF; -// enc28j60_set_bank(spi_device, EIR); -// spi_write_op(spi_device, ENC28J60_BIT_FIELD_CLR, EIR, EIR_DMAIF); - } - - /* LINK changed handler */ - if (eir & EIR_LINKIF) - { - rt_bool_t link_status; - - NET_DEBUG("EIR_LINKIF\r\n"); - link_status = enc28j60_check_link_status(spi_device); - - /* read PHIR to clear the flag */ - enc28j60_phy_read(spi_device, PHIR); - eir_clr |= EIR_LINKIF; -// enc28j60_set_bank(spi_device, EIR); -// spi_write_op(spi_device, ENC28J60_BIT_FIELD_CLR, EIR, EIR_LINKIF); - - eth_device_linkchange(&(enc28j60->parent), link_status); - } - - if (eir & EIR_TXIF) - { - /* A frame has been transmitted. */ - enc28j60_set_bank(spi_device, EIR); - spi_write_op(spi_device, ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXIF); - - tx_ack->free = RT_TRUE; - tx_ack = tx_ack->next; - if (tx_ack->free == RT_FALSE) - { - NET_DEBUG("[tx isr] Tx chain not empty, continue send the next pkt!\r\n"); - // TX start - spi_write(spi_device, ETXSTL, (tx_ack->addr) & 0xFF); - spi_write(spi_device, ETXSTH, (tx_ack->addr) >> 8); - // TX end - spi_write(spi_device, ETXNDL, (tx_ack->addr + tx_ack->len) & 0xFF); - spi_write(spi_device, ETXNDH, (tx_ack->addr + tx_ack->len) >> 8); - - spi_write_op(spi_device, ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRTS); - } - else - { - NET_DEBUG("[tx isr] Tx chain empty, stop!\r\n"); - } - - /* set event */ - rt_event_send(&tx_event, 0x01); - } - - /* wake up handler */ - if (eir & EIR_WOLIF) - { - NET_DEBUG("EIR_WOLIF\r\n"); - eir_clr |= EIR_WOLIF; -// enc28j60_set_bank(spi_device, EIR); -// spi_write_op(spi_device, ENC28J60_BIT_FIELD_CLR, EIR, EIR_WOLIF); - } - - /* TX Error handler */ - if ((eir & EIR_TXERIF) != 0) - { - NET_DEBUG("EIR_TXERIF re-start tx chain!\r\n"); - enc28j60_set_bank(spi_device, ECON1); - spi_write_op(spi_device, ENC28J60_BIT_FIELD_SET, ECON1, ECON1_TXRST); - spi_write_op(spi_device, ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_TXRST); - eir_clr |= EIR_TXERIF; -// enc28j60_set_bank(spi_device, EIR); -// spi_write_op(spi_device, ENC28J60_BIT_FIELD_CLR, EIR, EIR_TXERIF); - - /* re-init tx chain */ - _tx_chain_init(); - } - - /* RX Error handler */ - if ((eir & EIR_RXERIF) != 0) - { - NET_DEBUG("EIR_RXERIF re-start rx!\r\n"); - - NextPacketPtr = RXSTART_INIT; - enc28j60_set_bank(spi_device, ECON1); - spi_write_op(spi_device, ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXRST); - spi_write_op(spi_device, ENC28J60_BIT_FIELD_CLR, ECON1, ECON1_RXRST); - /* switch to bank 0. */ - enc28j60_set_bank(spi_device, ECON1); - /* enable packet reception. */ - spi_write_op(spi_device, ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); - eir_clr |= EIR_RXERIF; -// enc28j60_set_bank(spi_device, EIR); -// spi_write_op(spi_device, ENC28J60_BIT_FIELD_CLR, EIR, EIR_RXERIF); - } - - enc28j60_set_bank(spi_device, EIR); - spi_write_op(spi_device, ENC28J60_BIT_FIELD_CLR, EIR, eir_clr); - - eir = spi_read(spi_device, EIR); - } - - /* read pkt */ - pk_counter = spi_read(spi_device, EPKTCNT); - if (pk_counter) - { - /* Set the read pointer to the start of the received packet. */ - spi_write(spi_device, ERDPTL, (NextPacketPtr)); - spi_write(spi_device, ERDPTH, (NextPacketPtr) >> 8); - - /* read the next packet pointer. */ - NextPacketPtr = spi_read_op(spi_device, ENC28J60_READ_BUF_MEM, 0); - NextPacketPtr |= spi_read_op(spi_device, ENC28J60_READ_BUF_MEM, 0) << 8; - - /* read the packet length (see datasheet page 43). */ - len = spi_read_op(spi_device, ENC28J60_READ_BUF_MEM, 0); //0x54 - len |= spi_read_op(spi_device, ENC28J60_READ_BUF_MEM, 0) << 8; //5554 - - len -= 4; //remove the CRC count - - // read the receive status (see datasheet page 43) - rxstat = spi_read_op(spi_device, ENC28J60_READ_BUF_MEM, 0); - rxstat |= ((rt_uint16_t)spi_read_op(spi_device, ENC28J60_READ_BUF_MEM, 0)) << 8; - - // check CRC and symbol errors (see datasheet page 44, table 7-3): - // The ERXFCON.CRCEN is set by default. Normally we should not - // need to check this. - if ((rxstat & 0x80) == 0) - { - // invalid - len = 0; - } - else - { - /* allocation pbuf */ - p = pbuf_alloc(PBUF_LINK, len, PBUF_POOL); - if (p != RT_NULL) - { - struct pbuf *q; -#ifdef ETH_RX_DUMP - rt_size_t dump_count = 0; - rt_uint8_t *dump_ptr; - rt_size_t dump_i; - NET_DEBUG("rx_dump, size:%d\r\n", len); -#endif - for (q = p; q != RT_NULL; q = q->next) - { - uint8_t cmd = ENC28J60_READ_BUF_MEM; - rt_spi_send_then_recv(spi_device, &cmd, 1, q->payload, q->len); -#ifdef ETH_RX_DUMP - dump_ptr = q->payload; - for (dump_i = 0; dump_i < q->len; dump_i++) - { - NET_DEBUG("%02x ", *dump_ptr); - if (((dump_count + 1) % 8) == 0) - { - NET_DEBUG(" "); - } - if (((dump_count + 1) % 16) == 0) - { - NET_DEBUG("\r\n"); - } - dump_count++; - dump_ptr++; - } -#endif - } -#ifdef ETH_RX_DUMP - NET_DEBUG("\r\n"); -#endif - } - } - - /* Move the RX read pointer to the start of the next received packet. */ - /* This frees the memory we just read out. */ - spi_write(spi_device, ERXRDPTL, (NextPacketPtr)); - spi_write(spi_device, ERXRDPTH, (NextPacketPtr) >> 8); - - /* decrement the packet counter indicate we are done with this packet. */ - spi_write_op(spi_device, ENC28J60_BIT_FIELD_SET, ECON2, ECON2_PKTDEC); - } - else - { - /* switch to bank 0. */ - enc28j60_set_bank(spi_device, ECON1); - /* enable packet reception. */ - spi_write_op(spi_device, ENC28J60_BIT_FIELD_SET, ECON1, ECON1_RXEN); - - level |= EIE_PKTIE; - } - - /* enable enc28j60 interrupt */ - enc28j60_interrupt_enable(spi_device, level); - - enc28j60_unlock(dev); - - return p; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops enc28j60_ops = -{ - enc28j60_init, - enc28j60_open, - enc28j60_close, - enc28j60_read, - enc28j60_write, - enc28j60_control -}; -#endif - -rt_err_t enc28j60_attach(const char *spi_device_name) -{ - struct rt_spi_device *spi_device; - - spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name); - if (spi_device == RT_NULL) - { - NET_DEBUG("spi device %s not found!\r\n", 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 Modes 0 */ - cfg.max_hz = 20 * 1000 * 1000; /* SPI Interface with Clock Speeds Up to 20 MHz */ - rt_spi_configure(spi_device, &cfg); - } /* config spi */ - - memset(&enc28j60_dev, 0, sizeof(enc28j60_dev)); - - rt_event_init(&tx_event, "eth_tx", RT_IPC_FLAG_FIFO); - enc28j60_dev.spi_device = spi_device; - - /* detect device */ - { - uint16_t value; - - /* perform system reset. */ - spi_write_op(spi_device, ENC28J60_SOFT_RESET, 0, ENC28J60_SOFT_RESET); - rt_thread_delay(1); /* delay 20ms */ - - enc28j60_dev.emac_rev = spi_read(spi_device, EREVID); - value = enc28j60_phy_read(spi_device, PHHID2); - enc28j60_dev.phy_rev = value & 0x0F; - enc28j60_dev.phy_pn = (value >> 4) & 0x3F; - enc28j60_dev.phy_id = (enc28j60_phy_read(spi_device, PHHID1) | ((value >> 10) << 16)) << 3; - - if (enc28j60_dev.phy_id != 0x00280418) - { - NET_DEBUG("ENC28J60 PHY ID not correct!\r\n"); - NET_DEBUG("emac_rev:%d\r\n", enc28j60_dev.emac_rev); - NET_DEBUG("phy_rev:%02X\r\n", enc28j60_dev.phy_rev); - NET_DEBUG("phy_pn:%02X\r\n", enc28j60_dev.phy_pn); - NET_DEBUG("phy_id:%08X\r\n", enc28j60_dev.phy_id); - return RT_EIO; - } - } - - /* OUI 00-04-A3 (hex): Microchip Technology, Inc. */ - enc28j60_dev.dev_addr[0] = 0x00; - enc28j60_dev.dev_addr[1] = 0x04; - enc28j60_dev.dev_addr[2] = 0xA3; - /* set MAC address, only for test */ - enc28j60_dev.dev_addr[3] = 0x12; - enc28j60_dev.dev_addr[4] = 0x34; - enc28j60_dev.dev_addr[5] = 0x56; - - /* init rt-thread device struct */ - enc28j60_dev.parent.parent.type = RT_Device_Class_NetIf; -#ifdef RT_USING_DEVICE_OPS - enc28j60_dev.parent.parent.ops = &enc28j60_ops; -#else - enc28j60_dev.parent.parent.init = enc28j60_init; - enc28j60_dev.parent.parent.open = enc28j60_open; - enc28j60_dev.parent.parent.close = enc28j60_close; - enc28j60_dev.parent.parent.read = enc28j60_read; - enc28j60_dev.parent.parent.write = enc28j60_write; - enc28j60_dev.parent.parent.control = enc28j60_control; -#endif - - /* init rt-thread ethernet device struct */ - enc28j60_dev.parent.eth_rx = enc28j60_rx; - enc28j60_dev.parent.eth_tx = enc28j60_tx; - - rt_mutex_init(&enc28j60_dev.lock, "enc28j60", RT_IPC_FLAG_FIFO); - - eth_device_init(&(enc28j60_dev.parent), "e0"); - - return RT_EOK; -} - -#ifdef RT_USING_FINSH -#include -/* - * Debug routine to dump useful register contents - */ -static void enc28j60(void) -{ - struct rt_spi_device *spi_device = enc28j60_dev.spi_device; - enc28j60_lock(&enc28j60_dev); - - rt_kprintf("-- enc28j60 registers:\n"); - rt_kprintf("HwRevID: 0x%02X\n", spi_read(spi_device, EREVID)); - - rt_kprintf("Cntrl: ECON1 ECON2 ESTAT EIR EIE\n"); - rt_kprintf(" 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\n", - spi_read(spi_device, ECON1), - spi_read(spi_device, ECON2), - spi_read(spi_device, ESTAT), - spi_read(spi_device, EIR), - spi_read(spi_device, EIE)); - - rt_kprintf("MAC : MACON1 MACON3 MACON4\n"); - rt_kprintf(" 0x%02X 0x%02X 0x%02X\n", - spi_read(spi_device, MACON1), - spi_read(spi_device, MACON3), - spi_read(spi_device, MACON4)); - - rt_kprintf("Rx : ERXST ERXND ERXWRPT ERXRDPT ERXFCON EPKTCNT MAMXFL\n"); - rt_kprintf(" 0x%04X 0x%04X 0x%04X 0x%04X ", - (spi_read(spi_device, ERXSTH) << 8) | spi_read(spi_device, ERXSTL), - (spi_read(spi_device, ERXNDH) << 8) | spi_read(spi_device, ERXNDL), - (spi_read(spi_device, ERXWRPTH) << 8) | spi_read(spi_device, ERXWRPTL), - (spi_read(spi_device, ERXRDPTH) << 8) | spi_read(spi_device, ERXRDPTL)); - - rt_kprintf("0x%02X 0x%02X 0x%04X\n", - spi_read(spi_device, ERXFCON), - spi_read(spi_device, EPKTCNT), - (spi_read(spi_device, MAMXFLH) << 8) | spi_read(spi_device, MAMXFLL)); - - rt_kprintf("Tx : ETXST ETXND MACLCON1 MACLCON2 MAPHSUP\n"); - rt_kprintf(" 0x%04X 0x%04X 0x%02X 0x%02X 0x%02X\n", - (spi_read(spi_device, ETXSTH) << 8) | spi_read(spi_device, ETXSTL), - (spi_read(spi_device, ETXNDH) << 8) | spi_read(spi_device, ETXNDL), - spi_read(spi_device, MACLCON1), - spi_read(spi_device, MACLCON2), - spi_read(spi_device, MAPHSUP)); - - rt_kprintf("PHY : PHCON1 PHSTAT1\r\n"); - rt_kprintf(" 0x%04X 0x%04X\r\n", - enc28j60_phy_read(spi_device, PHCON1), - enc28j60_phy_read(spi_device, PHSTAT1)); - - enc28j60_unlock(&enc28j60_dev); -} -FINSH_FUNCTION_EXPORT(enc28j60, dump enc28j60 registers); -#endif diff --git a/IoTGateWay/components/drivers/spi/enc28j60.h b/IoTGateWay/components/drivers/spi/enc28j60.h deleted file mode 100644 index adff774748394..0000000000000 --- a/IoTGateWay/components/drivers/spi/enc28j60.h +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ -#ifndef EN28J60_H_INCLUDED -#define EN28J60_H_INCLUDED - -#include - -#include -#include -#include - -// ENC28J60 Control Registers -// Control register definitions are a combination of address, -// bank number, and Ethernet/MAC/PHY indicator bits. -// - Register address (bits 0-4) -// - Bank number (bits 5-6) -// - MAC/PHY indicator (bit 7) -#define ADDR_MASK 0x1F -#define BANK_MASK 0x60 -#define SPRD_MASK 0x80 -// All-bank registers -#define EIE 0x1B -#define EIR 0x1C -#define ESTAT 0x1D -#define ECON2 0x1E -#define ECON1 0x1F -// Bank 0 registers -#define ERDPTL (0x00|0x00) -#define ERDPTH (0x01|0x00) -#define EWRPTL (0x02|0x00) -#define EWRPTH (0x03|0x00) -#define ETXSTL (0x04|0x00) -#define ETXSTH (0x05|0x00) -#define ETXNDL (0x06|0x00) -#define ETXNDH (0x07|0x00) -#define ERXSTL (0x08|0x00) -#define ERXSTH (0x09|0x00) -#define ERXNDL (0x0A|0x00) -#define ERXNDH (0x0B|0x00) -#define ERXRDPTL (0x0C|0x00) -#define ERXRDPTH (0x0D|0x00) -#define ERXWRPTL (0x0E|0x00) -#define ERXWRPTH (0x0F|0x00) -#define EDMASTL (0x10|0x00) -#define EDMASTH (0x11|0x00) -#define EDMANDL (0x12|0x00) -#define EDMANDH (0x13|0x00) -#define EDMADSTL (0x14|0x00) -#define EDMADSTH (0x15|0x00) -#define EDMACSL (0x16|0x00) -#define EDMACSH (0x17|0x00) -// Bank 1 registers -#define EHT0 (0x00|0x20) -#define EHT1 (0x01|0x20) -#define EHT2 (0x02|0x20) -#define EHT3 (0x03|0x20) -#define EHT4 (0x04|0x20) -#define EHT5 (0x05|0x20) -#define EHT6 (0x06|0x20) -#define EHT7 (0x07|0x20) -#define EPMM0 (0x08|0x20) -#define EPMM1 (0x09|0x20) -#define EPMM2 (0x0A|0x20) -#define EPMM3 (0x0B|0x20) -#define EPMM4 (0x0C|0x20) -#define EPMM5 (0x0D|0x20) -#define EPMM6 (0x0E|0x20) -#define EPMM7 (0x0F|0x20) -#define EPMCSL (0x10|0x20) -#define EPMCSH (0x11|0x20) -#define EPMOL (0x14|0x20) -#define EPMOH (0x15|0x20) -#define EWOLIE (0x16|0x20) -#define EWOLIR (0x17|0x20) -#define ERXFCON (0x18|0x20) -#define EPKTCNT (0x19|0x20) -// Bank 2 registers -#define MACON1 (0x00|0x40|0x80) -#define MACON2 (0x01|0x40|0x80) -#define MACON3 (0x02|0x40|0x80) -#define MACON4 (0x03|0x40|0x80) -#define MABBIPG (0x04|0x40|0x80) -#define MAIPGL (0x06|0x40|0x80) -#define MAIPGH (0x07|0x40|0x80) -#define MACLCON1 (0x08|0x40|0x80) -#define MACLCON2 (0x09|0x40|0x80) -#define MAMXFLL (0x0A|0x40|0x80) -#define MAMXFLH (0x0B|0x40|0x80) -#define MAPHSUP (0x0D|0x40|0x80) -#define MICON (0x11|0x40|0x80) -#define MICMD (0x12|0x40|0x80) -#define MIREGADR (0x14|0x40|0x80) -#define MIWRL (0x16|0x40|0x80) -#define MIWRH (0x17|0x40|0x80) -#define MIRDL (0x18|0x40|0x80) -#define MIRDH (0x19|0x40|0x80) -// Bank 3 registers -#define MAADR1 (0x00|0x60|0x80) -#define MAADR0 (0x01|0x60|0x80) -#define MAADR3 (0x02|0x60|0x80) -#define MAADR2 (0x03|0x60|0x80) -#define MAADR5 (0x04|0x60|0x80) -#define MAADR4 (0x05|0x60|0x80) -#define EBSTSD (0x06|0x60) -#define EBSTCON (0x07|0x60) -#define EBSTCSL (0x08|0x60) -#define EBSTCSH (0x09|0x60) -#define MISTAT (0x0A|0x60|0x80) -#define EREVID (0x12|0x60) -#define ECOCON (0x15|0x60) -#define EFLOCON (0x17|0x60) -#define EPAUSL (0x18|0x60) -#define EPAUSH (0x19|0x60) -// PHY registers -#define PHCON1 0x00 -#define PHSTAT1 0x01 -#define PHHID1 0x02 -#define PHHID2 0x03 -#define PHCON2 0x10 -#define PHSTAT2 0x11 -#define PHIE 0x12 -#define PHIR 0x13 -#define PHLCON 0x14 - -// ENC28J60 ERXFCON Register Bit Definitions -#define ERXFCON_UCEN 0x80 -#define ERXFCON_ANDOR 0x40 -#define ERXFCON_CRCEN 0x20 -#define ERXFCON_PMEN 0x10 -#define ERXFCON_MPEN 0x08 -#define ERXFCON_HTEN 0x04 -#define ERXFCON_MCEN 0x02 -#define ERXFCON_BCEN 0x01 -// ENC28J60 EIE Register Bit Definitions -#define EIE_INTIE 0x80 -#define EIE_PKTIE 0x40 -#define EIE_DMAIE 0x20 -#define EIE_LINKIE 0x10 -#define EIE_TXIE 0x08 -#define EIE_WOLIE 0x04 -#define EIE_TXERIE 0x02 -#define EIE_RXERIE 0x01 -// ENC28J60 EIR Register Bit Definitions -#define EIR_PKTIF 0x40 -#define EIR_DMAIF 0x20 -#define EIR_LINKIF 0x10 -#define EIR_TXIF 0x08 -#define EIR_WOLIF 0x04 -#define EIR_TXERIF 0x02 -#define EIR_RXERIF 0x01 -// ENC28J60 ESTAT Register Bit Definitions -#define ESTAT_INT 0x80 -#define ESTAT_LATECOL 0x10 -#define ESTAT_RXBUSY 0x04 -#define ESTAT_TXABRT 0x02 -#define ESTAT_CLKRDY 0x01 -// ENC28J60 ECON2 Register Bit Definitions -#define ECON2_AUTOINC 0x80 -#define ECON2_PKTDEC 0x40 -#define ECON2_PWRSV 0x20 -#define ECON2_VRPS 0x08 -// ENC28J60 ECON1 Register Bit Definitions -#define ECON1_TXRST 0x80 -#define ECON1_RXRST 0x40 -#define ECON1_DMAST 0x20 -#define ECON1_CSUMEN 0x10 -#define ECON1_TXRTS 0x08 -#define ECON1_RXEN 0x04 -#define ECON1_BSEL1 0x02 -#define ECON1_BSEL0 0x01 -// ENC28J60 MACON1 Register Bit Definitions -#define MACON1_LOOPBK 0x10 -#define MACON1_TXPAUS 0x08 -#define MACON1_RXPAUS 0x04 -#define MACON1_PASSALL 0x02 -#define MACON1_MARXEN 0x01 -// ENC28J60 MACON2 Register Bit Definitions -#define MACON2_MARST 0x80 -#define MACON2_RNDRST 0x40 -#define MACON2_MARXRST 0x08 -#define MACON2_RFUNRST 0x04 -#define MACON2_MATXRST 0x02 -#define MACON2_TFUNRST 0x01 -// ENC28J60 MACON3 Register Bit Definitions -#define MACON3_PADCFG2 0x80 -#define MACON3_PADCFG1 0x40 -#define MACON3_PADCFG0 0x20 -#define MACON3_TXCRCEN 0x10 -#define MACON3_PHDRLEN 0x08 -#define MACON3_HFRMLEN 0x04 -#define MACON3_FRMLNEN 0x02 -#define MACON3_FULDPX 0x01 -// ENC28J60 MACON4 Register Bit Definitions -#define MACON4_DEFER (1<<6) -#define MACON4_BPEN (1<<5) -#define MACON4_NOBKOFF (1<<4) -// ENC28J60 MICMD Register Bit Definitions -#define MICMD_MIISCAN 0x02 -#define MICMD_MIIRD 0x01 -// ENC28J60 MISTAT Register Bit Definitions -#define MISTAT_NVALID 0x04 -#define MISTAT_SCAN 0x02 -#define MISTAT_BUSY 0x01 -// ENC28J60 PHY PHCON1 Register Bit Definitions -#define PHCON1_PRST 0x8000 -#define PHCON1_PLOOPBK 0x4000 -#define PHCON1_PPWRSV 0x0800 -#define PHCON1_PDPXMD 0x0100 -// ENC28J60 PHY PHSTAT1 Register Bit Definitions -#define PHSTAT1_PFDPX 0x1000 -#define PHSTAT1_PHDPX 0x0800 -#define PHSTAT1_LLSTAT 0x0004 -#define PHSTAT1_JBSTAT 0x0002 -/* ENC28J60 PHY PHSTAT2 Register Bit Definitions */ -#define PHSTAT2_TXSTAT (1 << 13) -#define PHSTAT2_RXSTAT (1 << 12) -#define PHSTAT2_COLSTAT (1 << 11) -#define PHSTAT2_LSTAT (1 << 10) -#define PHSTAT2_DPXSTAT (1 << 9) -#define PHSTAT2_PLRITY (1 << 5) -// ENC28J60 PHY PHCON2 Register Bit Definitions -#define PHCON2_FRCLINK 0x4000 -#define PHCON2_TXDIS 0x2000 -#define PHCON2_JABBER 0x0400 -#define PHCON2_HDLDIS 0x0100 -/* ENC28J60 PHY PHIE Register Bit Definitions */ -#define PHIE_PLNKIE (1 << 4) -#define PHIE_PGEIE (1 << 1) -/* ENC28J60 PHY PHIR Register Bit Definitions */ -#define PHIR_PLNKIF (1 << 4) -#define PHIR_PGEIF (1 << 1) - -// ENC28J60 Packet Control Byte Bit Definitions -#define PKTCTRL_PHUGEEN 0x08 -#define PKTCTRL_PPADEN 0x04 -#define PKTCTRL_PCRCEN 0x02 -#define PKTCTRL_POVERRIDE 0x01 - -/* ENC28J60 Transmit Status Vector */ -#define TSV_TXBYTECNT 0 -#define TSV_TXCOLLISIONCNT 16 -#define TSV_TXCRCERROR 20 -#define TSV_TXLENCHKERROR 21 -#define TSV_TXLENOUTOFRANGE 22 -#define TSV_TXDONE 23 -#define TSV_TXMULTICAST 24 -#define TSV_TXBROADCAST 25 -#define TSV_TXPACKETDEFER 26 -#define TSV_TXEXDEFER 27 -#define TSV_TXEXCOLLISION 28 -#define TSV_TXLATECOLLISION 29 -#define TSV_TXGIANT 30 -#define TSV_TXUNDERRUN 31 -#define TSV_TOTBYTETXONWIRE 32 -#define TSV_TXCONTROLFRAME 48 -#define TSV_TXPAUSEFRAME 49 -#define TSV_BACKPRESSUREAPP 50 -#define TSV_TXVLANTAGFRAME 51 - -#define TSV_SIZE 7 -#define TSV_BYTEOF(x) ((x) / 8) -#define TSV_BITMASK(x) (1 << ((x) % 8)) -#define TSV_GETBIT(x, y) (((x)[TSV_BYTEOF(y)] & TSV_BITMASK(y)) ? 1 : 0) - -/* ENC28J60 Receive Status Vector */ -#define RSV_RXLONGEVDROPEV 16 -#define RSV_CARRIEREV 18 -#define RSV_CRCERROR 20 -#define RSV_LENCHECKERR 21 -#define RSV_LENOUTOFRANGE 22 -#define RSV_RXOK 23 -#define RSV_RXMULTICAST 24 -#define RSV_RXBROADCAST 25 -#define RSV_DRIBBLENIBBLE 26 -#define RSV_RXCONTROLFRAME 27 -#define RSV_RXPAUSEFRAME 28 -#define RSV_RXUNKNOWNOPCODE 29 -#define RSV_RXTYPEVLAN 30 - -#define RSV_SIZE 6 -#define RSV_BITMASK(x) (1 << ((x) - 16)) -#define RSV_GETBIT(x, y) (((x) & RSV_BITMASK(y)) ? 1 : 0) - -// SPI operation codes -#define ENC28J60_READ_CTRL_REG 0x00 -#define ENC28J60_READ_BUF_MEM 0x3A -#define ENC28J60_WRITE_CTRL_REG 0x40 -#define ENC28J60_WRITE_BUF_MEM 0x7A -#define ENC28J60_BIT_FIELD_SET 0x80 -#define ENC28J60_BIT_FIELD_CLR 0xA0 -#define ENC28J60_SOFT_RESET 0xFF - -// The RXSTART_INIT should be zero. See Rev. B4 Silicon Errata -// buffer boundaries applied to internal 8K ram -// the entire available packet buffer space is allocated -// - -#define MAX_TX_PACKAGE_SIZE (1536) - -// start with recbuf at 0/ -#define RXSTART_INIT 0x0 -// receive buffer end -#define RXSTOP_INIT (0x1FFF - MAX_TX_PACKAGE_SIZE*2) - 1 -// start TX buffer at 0x1FFF-0x0600, pace for one full ethernet frame (~1500 bytes) - -#define TXSTART_INIT (0x1FFF - MAX_TX_PACKAGE_SIZE*2) -// stp TX buffer at end of mem -#define TXSTOP_INIT 0x1FFF - -// max frame length which the conroller will accept: -#define MAX_FRAMELEN 1518 - -#define MAX_ADDR_LEN 6 - -struct net_device -{ - /* inherit from ethernet device */ - struct eth_device parent; - - /* interface address info. */ - rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */ - - rt_uint8_t emac_rev; - rt_uint8_t phy_rev; - rt_uint8_t phy_pn; - rt_uint32_t phy_id; - - /* spi device */ - struct rt_spi_device *spi_device; - struct rt_mutex lock; -}; - -/* export function */ -extern rt_err_t enc28j60_attach(const char *spi_device_name); -extern void enc28j60_isr(void); - -#endif // EN28J60_H_INCLUDED diff --git a/IoTGateWay/components/drivers/spi/qspi_core.c b/IoTGateWay/components/drivers/spi/qspi_core.c deleted file mode 100644 index c9ff6a963799a..0000000000000 --- a/IoTGateWay/components/drivers/spi/qspi_core.c +++ /dev/null @@ -1,265 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2018-11-16 zylx first version. - */ - -#include - -rt_err_t rt_qspi_configure(struct rt_qspi_device *device, struct rt_qspi_configuration *cfg) -{ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(cfg != RT_NULL); - - struct rt_qspi_device *qspi_device = (struct rt_qspi_device *)device; - rt_err_t result = RT_EOK; - - /* copy configuration items */ - qspi_device->config.parent.mode = cfg->parent.mode; - qspi_device->config.parent.max_hz = cfg->parent.max_hz; - qspi_device->config.parent.data_width = cfg->parent.data_width; - qspi_device->config.parent.reserved = cfg->parent.reserved; - qspi_device->config.medium_size = cfg->medium_size; - qspi_device->config.ddr_mode = cfg->ddr_mode; - qspi_device->config.qspi_dl_width = cfg->qspi_dl_width; - - result = rt_spi_configure(&device->parent, &cfg->parent); - - return result; -} - -rt_err_t rt_qspi_bus_register(struct rt_spi_bus *bus, const char *name, const struct rt_spi_ops *ops) -{ - rt_err_t result = RT_EOK; - - result = rt_spi_bus_register(bus, name, ops); - if(result == RT_EOK) - { - /* set SPI bus to qspi modes */ - bus->mode = RT_SPI_BUS_MODE_QSPI; - } - - return result; -} - -rt_size_t rt_qspi_transfer_message(struct rt_qspi_device *device, struct rt_qspi_message *message) -{ - rt_err_t result; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(message != RT_NULL); - - result = rt_mutex_take(&(device->parent.bus->lock), RT_WAITING_FOREVER); - if (result != RT_EOK) - { - rt_set_errno(-RT_EBUSY); - - return 0; - } - - /* reset errno */ - rt_set_errno(RT_EOK); - - /* configure SPI bus */ - if (device->parent.bus->owner != &device->parent) - { - /* not the same owner as current, re-configure SPI bus */ - result = device->parent.bus->ops->configure(&device->parent, &device->parent.config); - if (result == RT_EOK) - { - /* set SPI bus owner */ - device->parent.bus->owner = &device->parent; - } - else - { - /* configure SPI bus failed */ - rt_set_errno(-RT_EIO); - goto __exit; - } - } - - /* transmit each SPI message */ - - result = device->parent.bus->ops->xfer(&device->parent, &message->parent); - if (result == 0) - { - rt_set_errno(-RT_EIO); - } - -__exit: - /* release bus lock */ - rt_mutex_release(&(device->parent.bus->lock)); - - return result; -} - -rt_err_t rt_qspi_send_then_recv(struct rt_qspi_device *device, const void *send_buf, rt_size_t send_length, void *recv_buf, rt_size_t recv_length) -{ - RT_ASSERT(send_buf); - RT_ASSERT(recv_buf); - RT_ASSERT(send_length != 0); - - struct rt_qspi_message message; - unsigned char *ptr = (unsigned char *)send_buf; - rt_size_t count = 0; - rt_err_t result = 0; - - message.instruction.content = ptr[0]; - message.instruction.qspi_lines = 1; - count++; - - /* get address */ - if (send_length > 1) - { - if (device->config.medium_size > 0x1000000 && send_length >= 5) - { - /* medium size greater than 16Mb, address size is 4 Byte */ - message.address.content = (ptr[1] << 24) | (ptr[2] << 16) | (ptr[3] << 8) | (ptr[4]); - message.address.size = 32; - count += 4; - } - else if (send_length >= 4) - { - /* address size is 3 Byte */ - message.address.content = (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]); - message.address.size = 24; - count += 3; - } - else - { - return -RT_ERROR; - } - message.address.qspi_lines = 1; - } - else - { - /* no address stage */ - message.address.content = 0 ; - message.address.qspi_lines = 0; - message.address.size = 0; - } - - message.alternate_bytes.content = 0; - message.alternate_bytes.size = 0; - message.alternate_bytes.qspi_lines = 0; - - /* set dummy cycles */ - if (count != send_length) - { - message.dummy_cycles = (send_length - count) * 8; - - } - else - { - message.dummy_cycles = 0; - } - - /* set recv buf and recv size */ - message.parent.recv_buf = recv_buf; - message.parent.send_buf = RT_NULL; - message.parent.length = recv_length; - message.parent.cs_take = 1; - message.parent.cs_release = 1; - - message.qspi_data_lines = 1; - - result = rt_qspi_transfer_message(device, &message); - if (result == 0) - { - result = -RT_EIO; - } - else - { - result = recv_length; - } - - return result; -} - -rt_err_t rt_qspi_send(struct rt_qspi_device *device, const void *send_buf, rt_size_t length) -{ - RT_ASSERT(send_buf); - RT_ASSERT(length != 0); - - struct rt_qspi_message message; - char *ptr = (char *)send_buf; - rt_size_t count = 0; - rt_err_t result = 0; - - message.instruction.content = ptr[0]; - message.instruction.qspi_lines = 1; - count++; - - /* get address */ - if (length > 1) - { - if (device->config.medium_size > 0x1000000 && length >= 5) - { - /* medium size greater than 16Mb, address size is 4 Byte */ - message.address.content = (ptr[1] << 24) | (ptr[2] << 16) | (ptr[3] << 8) | (ptr[4]); - message.address.size = 32; - message.address.qspi_lines = 1; - count += 4; - } - else if (length >= 4) - { - /* address size is 3 Byte */ - message.address.content = (ptr[1] << 16) | (ptr[2] << 8) | (ptr[3]); - message.address.size = 24; - message.address.qspi_lines = 1; - count += 3; - } - else - { - return -RT_ERROR; - } - - } - else - { - /* no address stage */ - message.address.content = 0 ; - message.address.qspi_lines = 0; - message.address.size = 0; - } - - message.alternate_bytes.content = 0; - message.alternate_bytes.size = 0; - message.alternate_bytes.qspi_lines = 0; - - message.dummy_cycles = 0; - - /* determine if there is data to send */ - if (length - count > 0) - { - message.qspi_data_lines = 1; - } - else - { - message.qspi_data_lines = 0; - - } - - /* set send buf and send size */ - message.parent.send_buf = ptr + count; - message.parent.recv_buf = RT_NULL; - message.parent.length = length - count; - message.parent.cs_take = 1; - message.parent.cs_release = 1; - - result = rt_qspi_transfer_message(device, &message); - if (result == 0) - { - result = -RT_EIO; - } - else - { - result = length; - } - - return result; -} diff --git a/IoTGateWay/components/drivers/spi/sfud/LICENSE b/IoTGateWay/components/drivers/spi/sfud/LICENSE deleted file mode 100644 index 14b97461499c0..0000000000000 --- a/IoTGateWay/components/drivers/spi/sfud/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016-2018 Armink (armink.ztl@gmail.com) - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -'Software'), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/IoTGateWay/components/drivers/spi/sfud/README.md b/IoTGateWay/components/drivers/spi/sfud/README.md deleted file mode 100644 index c732d06dbe677..0000000000000 --- a/IoTGateWay/components/drivers/spi/sfud/README.md +++ /dev/null @@ -1,296 +0,0 @@ -# SFUD (Serial Flash Universal Driver) 串行 Flash 通用驱动库 - ---- - -## 0、SFUD 是什么 - -[SFUD](https://github.com/armink/SFUD) 是一款开源的串行 SPI Flash 通用驱动库。由于现有市面的串行 Flash 种类居多,各个 Flash 的规格及命令存在差异, SFUD 就是为了解决这些 Flash 的差异现状而设计,让我们的产品能够支持不同品牌及规格的 Flash,提高了涉及到 Flash 功能的软件的可重用性及可扩展性,同时也可以规避 Flash 缺货或停产给产品所带来的风险。 - -- 主要特点:支持 SPI/QSPI 接口、面向对象(同时支持多个 Flash 对象)、可灵活裁剪、扩展性强、支持 4 字节地址 -- 资源占用 - - 标准占用:RAM:0.2KB ROM:5.5KB - - 最小占用:RAM:0.1KB ROM:3.6KB -- 设计思路: - - **什么是 SFDP** :它是 JEDEC (固态技术协会)制定的串行 Flash 功能的参数表标准,最新版 V1.6B ([点击这里查看](https://www.jedec.org/standards-documents/docs/jesd216b))。该标准规定了,每个 Flash 中会存在一个参数表,该表中会存放 Flash 容量、写粒度、擦除命令、地址模式等 Flash 规格参数。目前,除了部分厂家旧款 Flash 型号会不支持该标准,其他绝大多数新出厂的 Flash 均已支持 SFDP 标准。所以该库在初始化时会优先读取 SFDP 表参数。 - - **不支持 SFDP 怎么办** :如果该 Flash 不支持 SFDP 标准,SFUD 会查询配置文件 ( [`/sfud/inc/sfud_flash_def.h`](https://github.com/armink/SFUD/blob/4bee2d0417a7ce853cc7aa3639b03fe825611fd9/sfud/inc/sfud_flash_def.h#L116-L142) ) 中提供的 **Flash 参数信息表** 中是否支持该款 Flash。如果不支持,则可以在配置文件中添加该款 Flash 的参数信息(添加方法详细见 [2.5 添加库目前不支持的 Flash](#25-添加库目前不支持的-flash))。获取到了 Flash 的规格参数后,就可以实现对 Flash 的全部操作。 - -## 1、为什么选择 SFUD - -- 避免项目因 Flash 缺货、Flash 停产或产品扩容而带来的风险; -- 越来越多的项目将固件存储到串行 Flash 中,例如:ESP8266 的固件、主板中的 BIOS 及其他常见电子产品中的固件等等,但是各种 Flash 规格及命令不统一。使用 SFUD 即可避免,在相同功能的软件平台基础下,无法适配不同 Flash 种类的硬件平台的问题,提高软件的可重用性; -- 简化软件流程,降低开发难度。现在只需要配置好 SPI 通信,即可畅快的开始玩串行 Flash 了; -- 可以用来制作 Flash 编程器/烧写器 - -## 2、SFUD 如何使用 - -### 2.1 已支持 Flash - -下表为所有已在 Demo 平台上进行过真机测试过的 Flash。显示为 **不支持** SFDP 标准的 Flash 已经在 Flash 参数信息表中定义,更多不支持 SFDP 标准的 Flash 需要大家以后 **共同来完善和维护** **([Github](https://github.com/armink/SFUD)|[OSChina](http://git.oschina.net/armink/SFUD)|[Coding](https://coding.net/u/armink/p/SFUD/git))** 。 - -如果觉得这个开源项目很赞,可以点击 [项目主页](https://github.com/armink/SFUD) 右上角的 **Star** ,同时把它推荐给更多有需要的朋友。 - -|型号|制造商|容量|最高速度|SFDP 标准|QSPI 模式|备注| -|:--:|:----:|:--:|:--:|:--:|:--:|----| -|[W25Q40BV](http://microchip.ua/esp8266/W25Q40BV(EOL).pdf)|Winbond|4Mb|50Mhz|不支持|双线|已停产| -|[W25Q80DV](http://www.winbond.com/resource-files/w25q80dv_revg_07212015.pdf)|Winbond|8Mb|104Mhz|支持|双线|| -|[W25Q16BV](https://media.digikey.com/pdf/Data%20Sheets/Winbond%20PDFs/W25Q16BV.pdf)|Winbond|16Mb|104Mhz|不支持|双线| by [slipperstree](https://github.com/slipperstree)| -|[W25Q16CV](http://www.winbond.com/resource-files/da00-w25q16cvf1.pdf)|Winbond|16Mb|104Mhz|支持|未测试|| -|[W25Q16DV](http://www.winbond.com/resource-files/w25q16dv%20revk%2005232016%20doc.pdf)|Winbond|16Mb|104Mhz|支持|未测试| by [slipperstree](https://github.com/slipperstree)| -|[W25Q32BV](http://www.winbond.com/resource-files/w25q32bv_revi_100413_wo_automotive.pdf)|Winbond|32Mb|104Mhz|支持|双线|| -|[W25Q64CV](http://www.winbond.com/resource-files/w25q64cv_revh_052214[2].pdf)|Winbond|64Mb|80Mhz|支持|四线|| -|[W25Q128BV](http://www.winbond.com/resource-files/w25q128bv_revh_100313_wo_automotive.pdf)|Winbond|128Mb|104Mhz|支持|四线|| -|[W25Q256FV](http://www.winbond.com/resource-files/w25q256fv%20revi%2002262016%20kms.pdf)|Winbond|256Mb|104Mhz|支持|四线|| -|[MX25L3206E](http://www.macronix.com/Lists/DataSheet/Attachments/3199/MX25L3206E,%203V,%2032Mb,%20v1.5.pdf)|Macronix|32Mb|86MHz|支持|双线|| -|[KH25L4006E](http://www.macronix.com.hk/Lists/Datasheet/Attachments/117/KH25L4006E.pdf)|Macronix|4Mb|86Mhz|支持|未测试| by [JiapengLi](https://github.com/JiapengLi)| -|[KH25L3206E](http://www.macronix.com.hk/Lists/Datasheet/Attachments/131/KH25L3206E.pdf)|Macronix|32Mb|86Mhz|支持|双线|| -|[SST25VF016B](http://ww1.microchip.com/downloads/en/DeviceDoc/20005044C.pdf)|Microchip|16Mb|50MHz|不支持|不支持| SST 已被 Microchip 收购| -|[M25P40](https://www.micron.com/~/media/documents/products/data-sheet/nor-flash/serial-nor/m25p/m25p40.pdf)|Micron|4Mb|75Mhz|不支持|未测试| by [redocCheng](https://github.com/redocCheng)| -|[M25P80](https://www.micron.com/~/media/documents/products/data-sheet/nor-flash/serial-nor/m25p/m25p80.pdf)|Micron|8Mb|75Mhz|不支持|未测试| by [redocCheng](https://github.com/redocCheng)| -|[M25P32](https://www.micron.com/~/media/documents/products/data-sheet/nor-flash/serial-nor/m25p/m25p32.pdf)|Micron|32Mb|75Mhz|不支持|不支持|| -|[EN25Q32B](http://www.kean.com.au/oshw/WR703N/teardown/EN25Q32B%2032Mbit%20SPI%20Flash.pdf)|EON|32Mb|104MHz|不支持|未测试|| -|[GD25Q16B](http://www.gigadevice.com/product/detail/5/410.html)|GigaDevice|16Mb|120Mhz|不支持|未测试| by [TanekLiang](https://github.com/TanekLiang) | -|[GD25Q64B](http://www.gigadevice.com/product/detail/5/364.html)|GigaDevice|64Mb|120Mhz|不支持|双线|| -|[S25FL216K](http://www.cypress.com/file/197346/download)|Cypress|16Mb|65Mhz|不支持|双线|| -|[S25FL032P](http://www.cypress.com/file/196861/download)|Cypress|32Mb|104Mhz|不支持|未测试| by [yc_911](https://gitee.com/yc_911) | -|[S25FL164K](http://www.cypress.com/file/196886/download)|Cypress|64Mb|108Mhz|支持|未测试|| -|[A25L080](http://www.amictechnology.com/datasheets/A25L080.pdf)|AMIC|8Mb|100Mhz|不支持|双线|| -|[A25LQ64](http://www.amictechnology.com/datasheets/A25LQ64.pdf)|AMIC|64Mb|104Mhz|支持|支持|| -|[F25L004](http://www.esmt.com.tw/db/manager/upload/f25l004.pdf)|ESMT|4Mb|100Mhz|不支持|不支持|| -|[PCT25VF016B](http://pctgroup.com.tw/attachments/files/files/248_25VF016B-P.pdf)|PCT|16Mb|80Mhz|不支持|不支持|SST 授权许可,会被识别为 SST25VF016B| -|[AT45DB161E](http://www.adestotech.com/wp-content/uploads/doc8782.pdf)|ADESTO|16Mb|85MHz|不支持|不支持|ADESTO 收购 Atmel 串行闪存产品线| - -> 注:QSPI 模式中,双线表示支持双线快读,四线表示支持四线快读。 -> -> 一般情况下,支持四线快读的 FLASH 也支持两线快读。 - -### 2.2 API 说明 - -先说明下本库主要使用的一个结构体 `sfud_flash` 。其定义位于 `/sfud/inc/sfud_def.h`。每个 SPI Flash 会对应一个该结构体,该结构体指针下面统称为 Flash 设备对象。初始化成功后在 `sfud_flash->chip` 结构体中会存放 SPI Flash 的常见参数。如果 SPI Flash 还支持 SFDP ,还可以通过 `sfud_flash->sfdp` 看到更加全面的参数信息。以下很多函数都将使用 Flash 设备对象作为第一个入参,实现对指定 SPI Flash 的操作。 - -#### 2.2.1 初始化 SFUD 库 - -将会调用 `sfud_device_init` ,初始化 Flash 设备表中的全部设备。如果只有一个 Flash 也可以只使用 `sfud_device_init` 进行单一初始化。 - -> **注意**:初始化完的 SPI Flash 默认都 **已取消写保护** 状态,如需开启写保护,请使用 sfud_write_status 函数修改 SPI Flash 状态。 - -```C -sfud_err sfud_init(void) -``` - -#### 2.2.2 初始化指定的 Flash 设备 - -```C -sfud_err sfud_device_init(sfud_flash *flash) -``` - -|参数 |描述| -|:----- |:----| -|flash |待初始化的 Flash 设备| - -#### 2.2.3 使能快速读模式(仅当 SFUD 开启 QSPI 模式后可用) - -当 SFUD 开启 QSPI 模式后,SFUD 中的 Flash 驱动支持使用 QSPI 总线进行通信。相比传统的 SPI 模式,使用 QSPI 能够加速 Flash 数据的读取,但当数据需要写入时,由于 Flash 本身的数据写入速度慢于 SPI 传输速度,所以 QSPI 模式下的数据写入速度提升并不明显。 - -所以 SFUD 对于 QSPI 模式的支持仅限于快速读命令。通过该函数可以配置 Flash 所使用的 QSPI 总线的实际支持的数据线最大宽度,例如:1 线(默认值,即传统的 SPI 模式)、2 线、4 线。 - -设置后,SFUD 会去结合当前设定的 QSPI 总线数据线宽度,去 [QSPI Flash 扩展信息表](https://github.com/armink/SFUD/blob/069d2b409ec239f84d675b2c3d37894e908829e6/sfud/inc/sfud_flash_def.h#L149-L177) 中匹配最合适的、速度最快的快速读命令,之后用户在调用 sfud_read() 时,会使用 QSPI 模式的传输函数发送该命令。 - -```C -sfud_err sfud_qspi_fast_read_enable(sfud_flash *flash, uint8_t data_line_width) -``` - -| 参数 | 描述 | -| :-------------- | :------------------------------------------- | -| flash | Flash 设备 | -| data_line_width | QSPI 总线支持的数据线最大宽度,例如:1、2、4 | - -#### 2.2.4 获取 Flash 设备对象 - -在 SFUD 配置文件中会定义 Flash 设备表,负责存放所有将要使用的 Flash 设备对象,所以 SFUD 支持多个 Flash 设备同时驱动。设备表的配置在 `/sfud/inc/sfud_cfg.h` 中 `SFUD_FLASH_DEVICE_TABLE` 宏定义,详细配置方法参照 [2.3 配置方法 Flash](#23-配置方法))。本方法通过 Flash 设备位于设备表中索引值来返回 Flash 设备对象,超出设备表范围返回 `NULL` 。 - -```C -sfud_flash *sfud_get_device(size_t index) -``` - -|参数 |描述| -|:----- |:----| -|index |Flash 设备位于 FLash 设备表中的索引值| - -#### 2.2.5 读取 Flash 数据 - -```C -sfud_err sfud_read(const sfud_flash *flash, uint32_t addr, size_t size, uint8_t *data) -``` - -|参数 |描述| -|:----- |:----| -|flash |Flash 设备对象| -|addr |起始地址| -|size |从起始地址开始读取数据的总大小| -|data |读取到的数据| - -#### 2.2.6 擦除 Flash 数据 - -> 注意:擦除操作将会按照 Flash 芯片的擦除粒度(详见 Flash 数据手册,一般为 block 大小。初始化完成后,可以通过 `sfud_flash->chip.erase_gran` 查看)对齐,请注意保证起始地址和擦除数据大小按照 Flash 芯片的擦除粒度对齐,否则执行擦除操作后,将会导致其他数据丢失。 - -```C -sfud_err sfud_erase(const sfud_flash *flash, uint32_t addr, size_t size) -``` - -|参数 |描述| -|:----- |:----| -|flash |Flash 设备对象| -|addr |起始地址| -|size |从起始地址开始擦除数据的总大小| - -#### 2.2.7 擦除 Flash 全部数据 - -```C -sfud_err sfud_chip_erase(const sfud_flash *flash) -``` - -|参数 |描述| -|:----- |:----| -|flash |Flash 设备对象| - -#### 2.2.8 往 Flash 写数据 - -```C -sfud_err sfud_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data) -``` - -|参数 |描述| -|:----- |:----| -|flash |Flash 设备对象| -|addr |起始地址| -|size |从起始地址开始写入数据的总大小| -|data |待写入的数据| - -#### 2.2.9 先擦除再往 Flash 写数据 - -> 注意:擦除操作将会按照 Flash 芯片的擦除粒度(详见 Flash 数据手册,一般为 block 大小。初始化完成后,可以通过 `sfud_flash->chip.erase_gran` 查看)对齐,请注意保证起始地址和擦除数据大小按照 Flash 芯片的擦除粒度对齐,否则执行擦除操作后,将会导致其他数据丢失。 - -```C -sfud_err sfud_erase_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data) -``` - -|参数 |描述| -|:----- |:----| -|flash |Flash 设备对象| -|addr |起始地址| -|size |从起始地址开始写入数据的总大小| -|data |待写入的数据| - -#### 2.2.10 读取 Flash 状态 - -```C -sfud_err sfud_read_status(const sfud_flash *flash, uint8_t *status) -``` - -|参数 |描述| -|:----- |:----| -|flash |Flash 设备对象| -|status |当前状态寄存器值| - -#### 2.2.11 写(修改) Flash 状态 - -```C -sfud_err sfud_write_status(const sfud_flash *flash, bool is_volatile, uint8_t status) -``` - -|参数 |描述| -|:----- |:----| -|flash |Flash 设备对象| -|is_volatile |是否为易闪失的,true: 易闪失的,及断电后会丢失| -|status |当前状态寄存器值| - -### 2.3 配置方法 - -所有配置位于 `/sfud/inc/sfud_cfg.h` ,请参考下面的配置介绍,选择适合自己项目的配置。 - -#### 2.3.1 调试模式 - -打开/关闭 `SFUD_DEBUG_MODE` 宏定义 - -#### 2.3.2 是否使用 SFDP 参数功能 - -打开/关闭 `SFUD_USING_SFDP` 宏定义 - -> 注意:关闭后只会查询该库在 `/sfud/inc/sfud_flash_def.h` 中提供的 Flash 信息表。这样虽然会降低软件的适配性,但减少代码量。 - -#### 2.3.3 是否使用该库自带的 Flash 参数信息表 - -打开/关闭 `SFUD_USING_FLASH_INFO_TABLE` 宏定义 - -> 注意:关闭后该库只驱动支持 SFDP 规范的 Flash,也会适当的降低部分代码量。另外 2.3.2 及 2.3.3 这两个宏定义至少定义一种,也可以两种方式都选择。 - -#### 2.3.4 既不使用 SFDP ,也不使用 Flash 参数信息表 - -为了进一步降低代码量,`SFUD_USING_SFDP` 与 `SFUD_USING_FLASH_INFO_TABLE` 也可以 **都不定义** 。 - -此时,只要在定义 Flash 设备时,指定好 Flash 参数,之后再调用 `sfud_device_init` 对该设备进行初始化。参考如下代码: - -```C -sfud_flash sfud_norflash0 = { - .name = "norflash0", - .spi.name = "SPI1", - .chip = { "W25Q64FV", SFUD_MF_ID_WINBOND, 0x40, 0x17, 8L * 1024L * 1024L, SFUD_WM_PAGE_256B, 4096, 0x20 } }; -...... -sfud_device_init(&sfud_norflash0); -...... -``` - -#### 2.3.5 Flash 设备表 - -如果产品中存在多个 Flash ,可以添加 Flash 设备表。修改 `SFUD_FLASH_DEVICE_TABLE` 这个宏定义,示例如下: - -```C -enum { - SFUD_W25Q64CV_DEVICE_INDEX = 0, - SFUD_GD25Q64B_DEVICE_INDEX = 1, -}; - -#define SFUD_FLASH_DEVICE_TABLE \ -{ \ - [SFUD_W25Q64CV_DEVICE_INDEX] = {.name = "W25Q64CV", .spi.name = "SPI1"}, \ - [SFUD_GD25Q64B_DEVICE_INDEX] = {.name = "GD25Q64B", .spi.name = "SPI3"}, \ -} -``` - -上面定义了两个 Flash 设备(大部分产品一个足以),两个设备的名称为 `"W25Q64CV"` 及 `"GD25Q64B"` ,分别对应 `"SPI1"` 及 `"SPI3"` 这两个 SPI 设备名称(在移植 SPI 接口时会用到,位于 `/sfud/port/sfud_port.c` ), `SFUD_W25Q16CV_DEVICE_INDEX` 与 `SFUD_GD25Q64B_DEVICE_INDEX` 这两个枚举定义了两个设备位于设备表中的索引,可以通过 `sfud_get_device_table()` 方法获取到设备表,再配合这个索引值来访问指定的设备。 - -#### 2.3.6 QSPI 模式 - -打开/关闭 `SFUD_USING_QSPI` 宏定义 - -开启后,SFUD 也将支持使用 QSPI 总线连接的 Flash。 - -### 2.4 移植说明 - -移植文件位于 `/sfud/port/sfud_port.c` ,文件中的 `sfud_err sfud_spi_port_init(sfud_flash *flash)` 方法是库提供的移植方法,在里面完成各个设备 SPI 读写驱动(必选)、重试次数(必选)、重试接口(可选)及 SPI 锁(可选)的配置。更加详细的移植内容,可以参考 demo 中的各个平台的移植文件。 - -### 2.5 添加库目前不支持的 Flash - -这里需要修改 `/sfud/inc/sfdu_flash_def.h` ,所有已经支持的 Flash 见 `SFUD_FLASH_CHIP_TABLE` 宏定义,需要提前准备的 Flash 参数内容分别为:| 名称 | 制造商 ID | 类型 ID | 容量 ID | 容量 | 写模式 | 擦除粒度(擦除的最小单位) | 擦除粒度对应的命令 | 。这里以添加 兆易创新 ( GigaDevice ) 的 `GD25Q64B` Flash 来举例。 - -此款 Flash 为兆易创新的早期生产的型号,所以不支持 SFDP 标准。首先需要下载其数据手册,找到 0x9F 命令返回的 3 种 ID, 这里需要最后面两字节 ID ,即 `type id` 及 `capacity id` 。 `GD25Q64B` 对应这两个 ID 分别为 `0x40` 及 `0x17` 。上面要求的其他 Flash 参数都可以在数据手册中找到,这里要重点说明下 **写模式** 这个参数,库本身提供的写模式共计有 4 种,详见文件顶部的 `sfud_write_mode` 枚举类型,同一款 Flash 可以同时支持多种写模式,视情况而定。对于 `GD25Q64B` 而言,其支持的写模式应该为 `SFUD_WM_PAGE_256B` ,即写 1-256 字节每页。结合上述 `GD25Q64B` 的 Flash 参数应如下: - -``` - {"GD25Q64B", SFUD_MF_ID_GIGADEVICE, 0x40, 0x17, 8*1024*1024, SFUD_WM_PAGE_256B, 4096, 0x20}, -``` - -再将其增加到 `SFUD_FLASH_CHIP_TABLE` 宏定义末尾,即可完成该库对 `GD25Q64B` 的支持。 - -### 2.6 Demo - -目前已支持如下平台下的 Demo - -|路径 |平台描述| -|:----- |:----| -|[/demo/stm32f10x_non_os](https://github.com/armink/SFUD/tree/master/demo/stm32f10x_non_os) |STM32F10X 裸机平台| -|[/demo/stm32f2xx_rtt](https://github.com/armink/SFUD/tree/master/demo/stm32f2xx_rtt) |STM32F2XX + [RT-Thread](http://www.rt-thread.org/) 操作系统平台| -|[/demo/stm32l475_non_os_qspi](https://github.com/armink/SFUD/tree/master/demo/stm32l475_non_os_qspi) |STM32L475 + QSPI 模式 裸机平台| - -### 2.7 许可 - -采用 MIT 开源协议,细节请阅读项目中的 LICENSE 文件内容。 diff --git a/IoTGateWay/components/drivers/spi/sfud/inc/sfud.h b/IoTGateWay/components/drivers/spi/sfud/inc/sfud.h deleted file mode 100644 index 2b68c38216f70..0000000000000 --- a/IoTGateWay/components/drivers/spi/sfud/inc/sfud.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * This file is part of the Serial Flash Universal Driver Library. - * - * Copyright (c) 2016-2018, Armink, - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * 'Software'), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Function: It is an head file for this library. You can see all of the functions which can be called by user. - * Created on: 2016-04-23 - */ - -#ifndef _SFUD_H_ -#define _SFUD_H_ - -#include "sfud_def.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* ../src/sfup.c */ -/** - * SFUD library initialize. - * - * @return result - */ -sfud_err sfud_init(void); - -/** - * SFUD initialize by flash device - * - * @param flash flash device - * - * @return result - */ -sfud_err sfud_device_init(sfud_flash *flash); - -/** - * get flash device by its index which in the flash information table - * - * @param index the index which in the flash information table @see flash_table - * - * @return flash device - */ -sfud_flash *sfud_get_device(size_t index); - -/** - * get flash device total number on flash device information table @see flash_table - * - * @return flash device total number - */ -size_t sfud_get_device_num(void); - -/** - * get flash device information table @see flash_table - * - * @return flash device table pointer - */ -const sfud_flash *sfud_get_device_table(void); - -#ifdef SFUD_USING_QSPI -/** - * Enbale the fast read mode in QSPI flash mode. Default read mode is normal SPI mode. - * - * it will find the appropriate fast-read instruction to replace the read instruction(0x03) - * fast-read instruction @see SFUD_FLASH_EXT_INFO_TABLE - * - * @note When Flash is in QSPI mode, the method must be called after sfud_device_init(). - * - * @param flash flash device - * @param data_line_width the data lines max width which QSPI bus supported, such as 1, 2, 4 - * - * @return result - */ -sfud_err sfud_qspi_fast_read_enable(sfud_flash *flash, uint8_t data_line_width); -#endif /* SFUD_USING_QSPI */ - -/** - * read flash data - * - * @param flash flash device - * @param addr start address - * @param size read size - * @param data read data pointer - * - * @return result - */ -sfud_err sfud_read(const sfud_flash *flash, uint32_t addr, size_t size, uint8_t *data); - -/** - * erase flash data - * - * @note It will erase align by erase granularity. - * - * @param flash flash device - * @param addr start address - * @param size erase size - * - * @return result - */ -sfud_err sfud_erase(const sfud_flash *flash, uint32_t addr, size_t size); - -/** - * write flash data (no erase operate) - * - * @param flash flash device - * @param addr start address - * @param data write data - * @param size write size - * - * @return result - */ -sfud_err sfud_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data); - -/** - * erase and write flash data - * - * @param flash flash device - * @param addr start address - * @param size write size - * @param data write data - * - * @return result - */ -sfud_err sfud_erase_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data); - -/** - * erase all flash data - * - * @param flash flash device - * - * @return result - */ -sfud_err sfud_chip_erase(const sfud_flash *flash); - -/** - * read flash register status - * - * @param flash flash device - * @param status register status - * - * @return result - */ -sfud_err sfud_read_status(const sfud_flash *flash, uint8_t *status); - -/** - * write status register - * - * @param flash flash device - * @param is_volatile true: volatile mode, false: non-volatile mode - * @param status register status - * - * @return result - */ -sfud_err sfud_write_status(const sfud_flash *flash, bool is_volatile, uint8_t status); - -#ifdef __cplusplus -} -#endif - -#endif /* _SFUD_H_ */ diff --git a/IoTGateWay/components/drivers/spi/sfud/inc/sfud_cfg.h b/IoTGateWay/components/drivers/spi/sfud/inc/sfud_cfg.h deleted file mode 100644 index 3b7860062dc95..0000000000000 --- a/IoTGateWay/components/drivers/spi/sfud/inc/sfud_cfg.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * This file is part of the Serial Flash Universal Driver Library. - * - * Copyright (c) 2016, Armink, - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * 'Software'), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Function: It is the configure head file for this library. - * Created on: 2016-04-23 - */ - -#ifndef _SFUD_CFG_H_ -#define _SFUD_CFG_H_ - -#include - -/** - * It will print more information on debug mode. - * #define RT_DEBUG_SFUD open debug mode */ -#ifdef RT_DEBUG_SFUD -#define SFUD_DEBUG_MODE -#endif - -/** - * Using probe flash JEDEC SFDP parameter. - */ -#ifdef RT_SFUD_USING_SFDP -#define SFUD_USING_SFDP -#endif - -/** - * SFUD will support QSPI mode. - */ -#ifdef RT_SFUD_USING_QSPI -#define SFUD_USING_QSPI -#endif - -/** - * Using probe flash JEDEC ID then query defined supported flash chip information table. @see SFUD_FLASH_CHIP_TABLE - */ -#ifdef RT_SFUD_USING_FLASH_INFO_TABLE -#define SFUD_USING_FLASH_INFO_TABLE -#endif - -#define SFUD_FLASH_DEVICE_TABLE {{0}} - -#endif /* _SFUD_CFG_H_ */ diff --git a/IoTGateWay/components/drivers/spi/sfud/inc/sfud_def.h b/IoTGateWay/components/drivers/spi/sfud/inc/sfud_def.h deleted file mode 100644 index fe7876618ba6b..0000000000000 --- a/IoTGateWay/components/drivers/spi/sfud/inc/sfud_def.h +++ /dev/null @@ -1,296 +0,0 @@ -/* - * This file is part of the Serial Flash Universal Driver Library. - * - * Copyright (c) 2016-2018, Armink, - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * 'Software'), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Function: It is the macro definition head file for this library. - * Created on: 2016-04-23 - */ - -#ifndef _SFUD_DEF_H_ -#define _SFUD_DEF_H_ - -#include -#include -#include -#include -#include -#include "sfud_flash_def.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* debug print function. Must be implement by user. */ -#ifdef SFUD_DEBUG_MODE -#ifndef SFUD_DEBUG -#define SFUD_DEBUG(...) sfud_log_debug(__FILE__, __LINE__, __VA_ARGS__) -#endif /* SFUD_DEBUG */ -#else -#define SFUD_DEBUG(...) -#endif /* SFUD_DEBUG_MODE */ - -#ifndef SFUD_INFO -#define SFUD_INFO(...) sfud_log_info(__VA_ARGS__) -#endif - -/* assert for developer. */ -#ifdef SFUD_DEBUG_MODE -#define SFUD_ASSERT(EXPR) \ -if (!(EXPR)) \ -{ \ - SFUD_DEBUG("(%s) has assert failed at %s.", #EXPR, __FUNCTION__); \ - while (1); \ -} -#else -#define SFUD_ASSERT(EXPR) -#endif - -/** - * retry process - * - * @param delay delay function for every retry. NULL will not delay for every retry. - * @param retry retry counts - * @param result SFUD_ERR_TIMEOUT: retry timeout - */ -#define SFUD_RETRY_PROCESS(delay, retry, result) \ - void (*__delay_temp)(void) = (void (*)(void))delay; \ - if (retry == 0) {result = SFUD_ERR_TIMEOUT;break;} \ - else {if (__delay_temp) {__delay_temp();} retry --;} - -/* software version number */ -#define SFUD_SW_VERSION "1.1.0" -/* - * all defined supported command - */ -#ifndef SFUD_CMD_WRITE_ENABLE -#define SFUD_CMD_WRITE_ENABLE 0x06 -#endif - -#ifndef SFUD_CMD_WRITE_DISABLE -#define SFUD_CMD_WRITE_DISABLE 0x04 -#endif - -#ifndef SFUD_CMD_READ_STATUS_REGISTER -#define SFUD_CMD_READ_STATUS_REGISTER 0x05 -#endif - -#ifndef SFUD_VOLATILE_SR_WRITE_ENABLE -#define SFUD_VOLATILE_SR_WRITE_ENABLE 0x50 -#endif - -#ifndef SFUD_CMD_WRITE_STATUS_REGISTER -#define SFUD_CMD_WRITE_STATUS_REGISTER 0x01 -#endif - -#ifndef SFUD_CMD_PAGE_PROGRAM -#define SFUD_CMD_PAGE_PROGRAM 0x02 -#endif - -#ifndef SFUD_CMD_AAI_WORD_PROGRAM -#define SFUD_CMD_AAI_WORD_PROGRAM 0xAD -#endif - -#ifndef SFUD_CMD_ERASE_CHIP -#define SFUD_CMD_ERASE_CHIP 0xC7 -#endif - -#ifndef SFUD_CMD_READ_DATA -#define SFUD_CMD_READ_DATA 0x03 -#endif - -#ifndef SFUD_CMD_DUAL_OUTPUT_READ_DATA -#define SFUD_CMD_DUAL_OUTPUT_READ_DATA 0x3B -#endif - -#ifndef SFUD_CMD_DUAL_IO_READ_DATA -#define SFUD_CMD_DUAL_IO_READ_DATA 0xBB -#endif - -#ifndef SFUD_CMD_QUAD_IO_READ_DATA -#define SFUD_CMD_QUAD_IO_READ_DATA 0xEB -#endif - -#ifndef SFUD_CMD_QUAD_OUTPUT_READ_DATA -#define SFUD_CMD_QUAD_OUTPUT_READ_DATA 0x6B -#endif - -#ifndef SFUD_CMD_MANUFACTURER_DEVICE_ID -#define SFUD_CMD_MANUFACTURER_DEVICE_ID 0x90 -#endif - -#ifndef SFUD_CMD_JEDEC_ID -#define SFUD_CMD_JEDEC_ID 0x9F -#endif - -#ifndef SFUD_CMD_READ_UNIQUE_ID -#define SFUD_CMD_READ_UNIQUE_ID 0x4B -#endif - -#ifndef SFUD_CMD_READ_SFDP_REGISTER -#define SFUD_CMD_READ_SFDP_REGISTER 0x5A -#endif - -#ifndef SFUD_CMD_ENABLE_RESET -#define SFUD_CMD_ENABLE_RESET 0x66 -#endif - -#ifndef SFUD_CMD_RESET -#define SFUD_CMD_RESET 0x99 -#endif - -#ifndef SFUD_CMD_ENTER_4B_ADDRESS_MODE -#define SFUD_CMD_ENTER_4B_ADDRESS_MODE 0xB7 -#endif - -#ifndef SFUD_CMD_EXIT_4B_ADDRESS_MODE -#define SFUD_CMD_EXIT_4B_ADDRESS_MODE 0xE9 -#endif - -#ifndef SFUD_WRITE_MAX_PAGE_SIZE -#define SFUD_WRITE_MAX_PAGE_SIZE 256 -#endif - -/* send dummy data for read data */ -#ifndef SFUD_DUMMY_DATA -#define SFUD_DUMMY_DATA 0xFF -#endif - -/* maximum number of erase type support on JESD216 (V1.0) */ -#define SFUD_SFDP_ERASE_TYPE_MAX_NUM 4 - -/** - * status register bits - */ -enum { - SFUD_STATUS_REGISTER_BUSY = (1 << 0), /**< busing */ - SFUD_STATUS_REGISTER_WEL = (1 << 1), /**< write enable latch */ - SFUD_STATUS_REGISTER_SRP = (1 << 7), /**< status register protect */ -}; - -/** - * error code - */ -typedef enum { - SFUD_SUCCESS = 0, /**< success */ - SFUD_ERR_NOT_FOUND = 1, /**< not found or not supported */ - SFUD_ERR_WRITE = 2, /**< write error */ - SFUD_ERR_READ = 3, /**< read error */ - SFUD_ERR_TIMEOUT = 4, /**< timeout error */ - SFUD_ERR_ADDR_OUT_OF_BOUND = 5, /**< address is out of flash bound */ -} sfud_err; - -#ifdef SFUD_USING_QSPI -/** - * QSPI flash read cmd format - */ -typedef struct { - uint8_t instruction; - uint8_t instruction_lines; - uint8_t address_size; - uint8_t address_lines; - uint8_t alternate_bytes_lines; - uint8_t dummy_cycles; - uint8_t data_lines; -} sfud_qspi_read_cmd_format; -#endif /* SFUD_USING_QSPI */ - -/* SPI bus write read data function type */ -typedef sfud_err (*spi_write_read_func)(const uint8_t *write_buf, size_t write_size, uint8_t *read_buf, size_t read_size); - -#ifdef SFUD_USING_SFDP -/** - * the SFDP (Serial Flash Discoverable Parameters) parameter info which used on this library - */ -typedef struct { - bool available; /**< available when read SFDP OK */ - uint8_t major_rev; /**< SFDP Major Revision */ - uint8_t minor_rev; /**< SFDP Minor Revision */ - uint16_t write_gran; /**< write granularity (bytes) */ - uint8_t erase_4k; /**< 4 kilobyte erase is supported throughout the device */ - uint8_t erase_4k_cmd; /**< 4 Kilobyte erase command */ - bool sr_is_non_vola; /**< status register is supports non-volatile */ - uint8_t vola_sr_we_cmd; /**< volatile status register write enable command */ - bool addr_3_byte; /**< supports 3-Byte addressing */ - bool addr_4_byte; /**< supports 4-Byte addressing */ - uint32_t capacity; /**< flash capacity (bytes) */ - struct { - uint32_t size; /**< erase sector size (bytes). 0x00: not available */ - uint8_t cmd; /**< erase command */ - } eraser[SFUD_SFDP_ERASE_TYPE_MAX_NUM]; /**< supported eraser types table */ - //TODO lots of fast read-related stuff (like modes supported and number of wait states/dummy cycles needed in each) -} sfud_sfdp, *sfud_sfdp_t; -#endif - -/** - * SPI device - */ -typedef struct __sfud_spi { - /* SPI device name */ - char *name; - /* SPI bus write read data function */ - sfud_err (*wr)(const struct __sfud_spi *spi, const uint8_t *write_buf, size_t write_size, uint8_t *read_buf, - size_t read_size); -#ifdef SFUD_USING_QSPI - /* QSPI fast read function */ - sfud_err (*qspi_read)(const struct __sfud_spi *spi, uint32_t addr, sfud_qspi_read_cmd_format *qspi_read_cmd_format, - uint8_t *read_buf, size_t read_size); -#endif - /* lock SPI bus */ - void (*lock)(const struct __sfud_spi *spi); - /* unlock SPI bus */ - void (*unlock)(const struct __sfud_spi *spi); - /* some user data */ - void *user_data; -} sfud_spi, *sfud_spi_t; - -/** - * serial flash device - */ -typedef struct { - char *name; /**< serial flash name */ - size_t index; /**< index of flash device information table @see flash_table */ - sfud_flash_chip chip; /**< flash chip information */ - sfud_spi spi; /**< SPI device */ - bool init_ok; /**< initialize OK flag */ - bool addr_in_4_byte; /**< flash is in 4-Byte addressing */ - struct { - void (*delay)(void); /**< every retry's delay */ - size_t times; /**< default times for error retry */ - } retry; - void *user_data; /**< some user data */ - -#ifdef SFUD_USING_QSPI - sfud_qspi_read_cmd_format read_cmd_format; /**< fast read cmd format */ -#endif - -#ifdef SFUD_USING_SFDP - sfud_sfdp sfdp; /**< serial flash discoverable parameters by JEDEC standard */ -#endif - -} sfud_flash, *sfud_flash_t; - -#ifdef __cplusplus -} -#endif - -#endif /* _SFUD_DEF_H_ */ diff --git a/IoTGateWay/components/drivers/spi/sfud/inc/sfud_flash_def.h b/IoTGateWay/components/drivers/spi/sfud/inc/sfud_flash_def.h deleted file mode 100644 index 13a0e702a8ea6..0000000000000 --- a/IoTGateWay/components/drivers/spi/sfud/inc/sfud_flash_def.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * This file is part of the Serial Flash Universal Driver Library. - * - * Copyright (c) 2016-2018, Armink, - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * 'Software'), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Function: It is the flash types and specification macro definition head file for this library. - * Created on: 2016-06-09 - */ - -#ifndef _SFUD_FLASH_DEF_H_ -#define _SFUD_FLASH_DEF_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * flash program(write) data mode - */ -enum sfud_write_mode { - SFUD_WM_PAGE_256B = 1 << 0, /**< write 1 to 256 bytes per page */ - SFUD_WM_BYTE = 1 << 1, /**< byte write */ - SFUD_WM_AAI = 1 << 2, /**< auto address increment */ - SFUD_WM_DUAL_BUFFER = 1 << 3, /**< dual-buffer write, like AT45DB series */ -}; - -/* manufacturer information */ -typedef struct { - char *name; - uint8_t id; -} sfud_mf; - -/* flash chip information */ -typedef struct { - char *name; /**< flash chip name */ - uint8_t mf_id; /**< manufacturer ID */ - uint8_t type_id; /**< memory type ID */ - uint8_t capacity_id; /**< capacity ID */ - uint32_t capacity; /**< flash capacity (bytes) */ - uint16_t write_mode; /**< write mode @see sfud_write_mode */ - uint32_t erase_gran; /**< erase granularity (bytes) */ - uint8_t erase_gran_cmd; /**< erase granularity size block command */ -} sfud_flash_chip; - -#ifdef SFUD_USING_QSPI -/* QSPI flash chip's extended information compared with SPI flash */ -typedef struct { - uint8_t mf_id; /**< manufacturer ID */ - uint8_t type_id; /**< memory type ID */ - uint8_t capacity_id; /**< capacity ID */ - uint8_t read_mode; /**< supported read mode on this qspi flash chip */ -} sfud_qspi_flash_ext_info; -#endif - -/* SFUD support manufacturer JEDEC ID */ -#define SFUD_MF_ID_CYPRESS 0x01 -#define SFUD_MF_ID_FUJITSU 0x04 -#define SFUD_MF_ID_EON 0x1C -#define SFUD_MF_ID_ATMEL 0x1F -#define SFUD_MF_ID_MICRON 0x20 -#define SFUD_MF_ID_AMIC 0x37 -#define SFUD_MF_ID_SANYO 0x62 -#define SFUD_MF_ID_INTEL 0x89 -#define SFUD_MF_ID_ESMT 0x8C -#define SFUD_MF_ID_FUDAN 0xA1 -#define SFUD_MF_ID_HYUNDAI 0xAD -#define SFUD_MF_ID_SST 0xBF -#define SFUD_MF_ID_MICRONIX 0xC2 -#define SFUD_MF_ID_GIGADEVICE 0xC8 -#define SFUD_MF_ID_ISSI 0xD5 -#define SFUD_MF_ID_WINBOND 0xEF - -/* SFUD supported manufacturer information table */ -#define SFUD_MF_TABLE \ -{ \ - {"Cypress", SFUD_MF_ID_CYPRESS}, \ - {"Fujitsu", SFUD_MF_ID_FUJITSU}, \ - {"EON", SFUD_MF_ID_EON}, \ - {"Atmel", SFUD_MF_ID_ATMEL}, \ - {"Micron", SFUD_MF_ID_MICRON}, \ - {"AMIC", SFUD_MF_ID_AMIC}, \ - {"Sanyo", SFUD_MF_ID_SANYO}, \ - {"Intel", SFUD_MF_ID_INTEL}, \ - {"ESMT", SFUD_MF_ID_ESMT}, \ - {"Fudan", SFUD_MF_ID_FUDAN}, \ - {"Hyundai", SFUD_MF_ID_HYUNDAI}, \ - {"SST", SFUD_MF_ID_SST}, \ - {"GigaDevice", SFUD_MF_ID_GIGADEVICE}, \ - {"ISSI", SFUD_MF_ID_ISSI}, \ - {"Winbond", SFUD_MF_ID_WINBOND}, \ - {"Micronix", SFUD_MF_ID_MICRONIX}, \ -} - -#ifdef SFUD_USING_FLASH_INFO_TABLE -/* SFUD supported flash chip information table. If the flash not support JEDEC JESD216 standard, - * then the SFUD will find the flash chip information by this table. You can add other flash to here then - * notice me for update it. The configuration information name and index reference the sfud_flash_chip structure. - * | name | mf_id | type_id | capacity_id | capacity | write_mode | erase_gran | erase_gran_cmd | - */ -#define SFUD_FLASH_CHIP_TABLE \ -{ \ - {"AT45DB161E", SFUD_MF_ID_ATMEL, 0x26, 0x00, 2L*1024L*1024L, SFUD_WM_BYTE|SFUD_WM_DUAL_BUFFER, 512, 0x81}, \ - {"W25Q40BV", SFUD_MF_ID_WINBOND, 0x40, 0x13, 512L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \ - {"W25Q16BV", SFUD_MF_ID_WINBOND, 0x40, 0x15, 2L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \ - {"W25Q64DW", SFUD_MF_ID_WINBOND, 0x60, 0x17, 8L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \ - {"W25Q128BV", SFUD_MF_ID_WINBOND, 0x40, 0x18, 16L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \ - {"W25Q256FV", SFUD_MF_ID_WINBOND, 0x40, 0x19, 32L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \ - {"SST25VF016B", SFUD_MF_ID_SST, 0x25, 0x41, 2L*1024L*1024L, SFUD_WM_BYTE|SFUD_WM_AAI, 4096, 0x20}, \ - {"M25P32", SFUD_MF_ID_MICRON, 0x20, 0x16, 4L*1024L*1024L, SFUD_WM_PAGE_256B, 64L*1024L, 0xD8}, \ - {"M25P80", SFUD_MF_ID_MICRON, 0x20, 0x14, 1L*1024L*1024L, SFUD_WM_PAGE_256B, 64L*1024L, 0xD8}, \ - {"M25P40", SFUD_MF_ID_MICRON, 0x20, 0x13, 512L*1024L, SFUD_WM_PAGE_256B, 64L*1024L, 0xD8}, \ - {"EN25Q32B", SFUD_MF_ID_EON, 0x30, 0x16, 4L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \ - {"GD25Q64B", SFUD_MF_ID_GIGADEVICE, 0x40, 0x17, 8L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \ - {"GD25Q16B", SFUD_MF_ID_GIGADEVICE, 0x40, 0x15, 2L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \ - {"S25FL216K", SFUD_MF_ID_CYPRESS, 0x40, 0x15, 2L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \ - {"S25FL032P", SFUD_MF_ID_CYPRESS, 0x02, 0x15, 4L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \ - {"A25L080", SFUD_MF_ID_AMIC, 0x30, 0x14, 1L*1024L*1024L, SFUD_WM_PAGE_256B, 4096, 0x20}, \ - {"F25L004", SFUD_MF_ID_ESMT, 0x20, 0x13, 512L*1024L, SFUD_WM_BYTE|SFUD_WM_AAI, 4096, 0x20}, \ - {"PCT25VF016B", SFUD_MF_ID_SST, 0x25, 0x41, 2L*1024L*1024L, SFUD_WM_BYTE|SFUD_WM_AAI, 4096, 0x20}, \ -} -#endif /* SFUD_USING_FLASH_INFO_TABLE */ - -#ifdef SFUD_USING_QSPI -/* This table saves flash read-fast instructions in QSPI mode, - * SFUD can use this table to select the most appropriate read instruction for flash. - * | mf_id | type_id | capacity_id | qspi_read_mode | - */ -#define SFUD_FLASH_EXT_INFO_TABLE \ -{ \ - /* W25Q40BV */ \ - {SFUD_MF_ID_WINBOND, 0x40, 0x13, NORMAL_SPI_READ|DUAL_OUTPUT}, \ - /* W25Q80JV */ \ - {SFUD_MF_ID_WINBOND, 0x40, 0x14, NORMAL_SPI_READ|DUAL_OUTPUT}, \ - /* W25Q16BV */ \ - {SFUD_MF_ID_WINBOND, 0x40, 0x15, NORMAL_SPI_READ|DUAL_OUTPUT}, \ - /* W25Q32BV */ \ - {SFUD_MF_ID_WINBOND, 0x40, 0x16, NORMAL_SPI_READ|DUAL_OUTPUT}, \ - /* W25Q64JV */ \ - {SFUD_MF_ID_WINBOND, 0x40, 0x17, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_OUTPUT|QUAD_IO}, \ - /* W25Q128JV */ \ - {SFUD_MF_ID_WINBOND, 0x40, 0x18, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_OUTPUT|QUAD_IO}, \ - /* W25Q256FV */ \ - {SFUD_MF_ID_WINBOND, 0x40, 0x19, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_OUTPUT|QUAD_IO}, \ - /* EN25Q32B */ \ - {SFUD_MF_ID_EON, 0x30, 0x16, NORMAL_SPI_READ|DUAL_OUTPUT|QUAD_IO}, \ - /* S25FL216K */ \ - {SFUD_MF_ID_CYPRESS, 0x40, 0x15, NORMAL_SPI_READ|DUAL_OUTPUT}, \ - /* A25L080 */ \ - {SFUD_MF_ID_AMIC, 0x30, 0x14, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO}, \ - /* A25LQ64 */ \ - {SFUD_MF_ID_AMIC, 0x40, 0x17, NORMAL_SPI_READ|DUAL_OUTPUT|DUAL_IO|QUAD_IO}, \ - /* MX25L3206E and KH25L3206E */ \ - {SFUD_MF_ID_MICRONIX, 0x20, 0x16, NORMAL_SPI_READ|DUAL_OUTPUT}, \ - /* GD25Q64B */ \ - {SFUD_MF_ID_GIGADEVICE, 0x40, 0x17, NORMAL_SPI_READ|DUAL_OUTPUT}, \ -} -#endif /* SFUD_USING_QSPI */ - -#ifdef __cplusplus -} -#endif - -#endif /* _SFUD_FLASH_DEF_H_ */ diff --git a/IoTGateWay/components/drivers/spi/sfud/src/sfud.c b/IoTGateWay/components/drivers/spi/sfud/src/sfud.c deleted file mode 100644 index f666b06806c64..0000000000000 --- a/IoTGateWay/components/drivers/spi/sfud/src/sfud.c +++ /dev/null @@ -1,1036 +0,0 @@ -/* - * This file is part of the Serial Flash Universal Driver Library. - * - * Copyright (c) 2016-2018, Armink, - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * 'Software'), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Function: serial flash operate functions by SFUD lib. - * Created on: 2016-04-23 - */ - -#include "../inc/sfud.h" -#include - -/* send dummy data for read data */ -#define DUMMY_DATA 0xFF - -#ifndef SFUD_FLASH_DEVICE_TABLE -#error "Please configure the flash device information table in (in sfud_cfg.h)." -#endif - -/* user configured flash device information table */ -static sfud_flash flash_table[] = SFUD_FLASH_DEVICE_TABLE; -/* supported manufacturer information table */ -static const sfud_mf mf_table[] = SFUD_MF_TABLE; - -#ifdef SFUD_USING_FLASH_INFO_TABLE -/* supported flash chip information table */ -static const sfud_flash_chip flash_chip_table[] = SFUD_FLASH_CHIP_TABLE; -#endif - -#ifdef SFUD_USING_QSPI -/** - * flash read data mode - */ -enum sfud_qspi_read_mode { - NORMAL_SPI_READ = 1 << 0, /**< mormal spi read mode */ - DUAL_OUTPUT = 1 << 1, /**< qspi fast read dual output */ - DUAL_IO = 1 << 2, /**< qspi fast read dual input/output */ - QUAD_OUTPUT = 1 << 3, /**< qspi fast read quad output */ - QUAD_IO = 1 << 4, /**< qspi fast read quad input/output */ -}; - -/* QSPI flash chip's extended information table */ -static const sfud_qspi_flash_ext_info qspi_flash_ext_info_table[] = SFUD_FLASH_EXT_INFO_TABLE; -#endif /* SFUD_USING_QSPI */ - -static sfud_err software_init(const sfud_flash *flash); -static sfud_err hardware_init(sfud_flash *flash); -static sfud_err page256_or_1_byte_write(const sfud_flash *flash, uint32_t addr, size_t size, uint16_t write_gran, - const uint8_t *data); -static sfud_err aai_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data); -static sfud_err wait_busy(const sfud_flash *flash); -static sfud_err reset(const sfud_flash *flash); -static sfud_err read_jedec_id(sfud_flash *flash); -static sfud_err set_write_enabled(const sfud_flash *flash, bool enabled); -static sfud_err set_4_byte_address_mode(sfud_flash *flash, bool enabled); -static void make_adress_byte_array(const sfud_flash *flash, uint32_t addr, uint8_t *array); - -/* ../port/sfup_port.c */ -extern void sfud_log_debug(const char *file, const long line, const char *format, ...); -extern void sfud_log_info(const char *format, ...); - -/** - * SFUD initialize by flash device - * - * @param flash flash device - * - * @return result - */ -sfud_err sfud_device_init(sfud_flash *flash) { - sfud_err result = SFUD_SUCCESS; - - /* hardware initialize */ - result = hardware_init(flash); - if (result == SFUD_SUCCESS) { - result = software_init(flash); - } - if (result == SFUD_SUCCESS) { - flash->init_ok = true; - SFUD_INFO("%s flash device is initialize success.", flash->name); - } else { - flash->init_ok = false; - SFUD_INFO("Error: %s flash device is initialize fail.", flash->name); - } - - return result; -} - -/** - * SFUD library initialize. - * - * @return result - */ -sfud_err sfud_init(void) { - sfud_err cur_flash_result = SFUD_SUCCESS, all_flash_result = SFUD_SUCCESS; - size_t i; - - SFUD_DEBUG("Start initialize Serial Flash Universal Driver(SFUD) V%s.", SFUD_SW_VERSION); - SFUD_DEBUG("You can get the latest version on https://github.com/armink/SFUD ."); - /* initialize all flash device in flash device table */ - for (i = 0; i < sizeof(flash_table) / sizeof(sfud_flash); i++) { - /* initialize flash device index of flash device information table */ - flash_table[i].index = i; - cur_flash_result = sfud_device_init(&flash_table[i]); - - if (cur_flash_result != SFUD_SUCCESS) { - all_flash_result = cur_flash_result; - } - } - - return all_flash_result; -} - -/** - * get flash device by its index which in the flash information table - * - * @param index the index which in the flash information table @see flash_table - * - * @return flash device - */ -sfud_flash *sfud_get_device(size_t index) { - if (index < sfud_get_device_num()) { - return &flash_table[index]; - } else { - return NULL; - } -} - -/** - * get flash device total number on flash device information table @see flash_table - * - * @return flash device total number - */ -size_t sfud_get_device_num(void) { - return sizeof(flash_table) / sizeof(sfud_flash); -} - -/** - * get flash device information table @see flash_table - * - * @return flash device table pointer - */ -const sfud_flash *sfud_get_device_table(void) { - return flash_table; -} - -#ifdef SFUD_USING_QSPI -static void qspi_set_read_cmd_format(sfud_flash *flash, uint8_t ins, uint8_t ins_lines, uint8_t addr_lines, - uint8_t dummy_cycles, uint8_t data_lines) { - /* if medium size greater than 16Mb, use 4-Byte address, instruction should be added one */ - if (flash->chip.capacity <= 0x1000000) { - flash->read_cmd_format.instruction = ins; - flash->read_cmd_format.address_size = 24; - } else { - flash->read_cmd_format.instruction = ins + 1; - flash->read_cmd_format.address_size = 32; - } - - flash->read_cmd_format.instruction_lines = ins_lines; - flash->read_cmd_format.address_lines = addr_lines; - flash->read_cmd_format.alternate_bytes_lines = 0; - flash->read_cmd_format.dummy_cycles = dummy_cycles; - flash->read_cmd_format.data_lines = data_lines; -} - -/** - * Enbale the fast read mode in QSPI flash mode. Default read mode is normal SPI mode. - * - * it will find the appropriate fast-read instruction to replace the read instruction(0x03) - * fast-read instruction @see SFUD_FLASH_EXT_INFO_TABLE - * - * @note When Flash is in QSPI mode, the method must be called after sfud_device_init(). - * - * @param flash flash device - * @param data_line_width the data lines max width which QSPI bus supported, such as 1, 2, 4 - * - * @return result - */ -sfud_err sfud_qspi_fast_read_enable(sfud_flash *flash, uint8_t data_line_width) { - size_t i = 0; - uint8_t read_mode = NORMAL_SPI_READ; - sfud_err result = SFUD_SUCCESS; - - SFUD_ASSERT(flash); - SFUD_ASSERT(data_line_width == 1 || data_line_width == 2 || data_line_width == 4); - - /* get read_mode, If don't found, the default is SFUD_QSPI_NORMAL_SPI_READ */ - for (i = 0; i < sizeof(qspi_flash_ext_info_table) / sizeof(sfud_qspi_flash_ext_info); i++) { - if ((qspi_flash_ext_info_table[i].mf_id == flash->chip.mf_id) - && (qspi_flash_ext_info_table[i].type_id == flash->chip.type_id) - && (qspi_flash_ext_info_table[i].capacity_id == flash->chip.capacity_id)) { - read_mode = qspi_flash_ext_info_table[i].read_mode; - } - } - - /* determine qspi supports which read mode and set read_cmd_format struct */ - switch (data_line_width) { - case 1: - qspi_set_read_cmd_format(flash, SFUD_CMD_READ_DATA, 1, 1, 0, 1); - break; - case 2: - if (read_mode & DUAL_IO) { - qspi_set_read_cmd_format(flash, SFUD_CMD_DUAL_IO_READ_DATA, 1, 2, 8, 2); - } else if (read_mode & DUAL_OUTPUT) { - qspi_set_read_cmd_format(flash, SFUD_CMD_DUAL_OUTPUT_READ_DATA, 1, 1, 8, 2); - } else { - qspi_set_read_cmd_format(flash, SFUD_CMD_READ_DATA, 1, 1, 0, 1); - } - break; - case 4: - if (read_mode & QUAD_IO) { - qspi_set_read_cmd_format(flash, SFUD_CMD_QUAD_IO_READ_DATA, 1, 4, 6, 4); - } else if (read_mode & QUAD_OUTPUT) { - qspi_set_read_cmd_format(flash, SFUD_CMD_QUAD_OUTPUT_READ_DATA, 1, 1, 8, 4); - } else { - qspi_set_read_cmd_format(flash, SFUD_CMD_READ_DATA, 1, 1, 0, 1); - } - break; - } - - return result; -} -#endif /* SFUD_USING_QSPI */ - -/** - * hardware initialize - */ -static sfud_err hardware_init(sfud_flash *flash) { - extern sfud_err sfud_spi_port_init(sfud_flash * flash); - - sfud_err result = SFUD_SUCCESS; - size_t i; - - SFUD_ASSERT(flash); - - result = sfud_spi_port_init(flash); - if (result != SFUD_SUCCESS) { - return result; - } - -#ifdef SFUD_USING_QSPI - /* set default read instruction */ - flash->read_cmd_format.instruction = SFUD_CMD_READ_DATA; -#endif /* SFUD_USING_QSPI */ - - /* SPI write read function must be initialize */ - SFUD_ASSERT(flash->spi.wr); - /* if the user don't configure flash chip information then using SFDP parameter or static flash parameter table */ - if (flash->chip.capacity == 0 || flash->chip.write_mode == 0 || flash->chip.erase_gran == 0 - || flash->chip.erase_gran_cmd == 0) { - /* read JEDEC ID include manufacturer ID, memory type ID and flash capacity ID */ - result = read_jedec_id(flash); - if (result != SFUD_SUCCESS) { - return result; - } - -#ifdef SFUD_USING_SFDP - extern bool sfud_read_sfdp(sfud_flash *flash); - /* read SFDP parameters */ - if (sfud_read_sfdp(flash)) { - flash->chip.name = NULL; - flash->chip.capacity = flash->sfdp.capacity; - /* only 1 byte or 256 bytes write mode for SFDP */ - if (flash->sfdp.write_gran == 1) { - flash->chip.write_mode = SFUD_WM_BYTE; - } else { - flash->chip.write_mode = SFUD_WM_PAGE_256B; - } - /* find the the smallest erase sector size for eraser. then will use this size for erase granularity */ - flash->chip.erase_gran = flash->sfdp.eraser[0].size; - flash->chip.erase_gran_cmd = flash->sfdp.eraser[0].cmd; - for (i = 1; i < SFUD_SFDP_ERASE_TYPE_MAX_NUM; i++) { - if (flash->sfdp.eraser[i].size != 0 && flash->chip.erase_gran > flash->sfdp.eraser[i].size) { - flash->chip.erase_gran = flash->sfdp.eraser[i].size; - flash->chip.erase_gran_cmd = flash->sfdp.eraser[i].cmd; - } - } - } else { -#endif - -#ifdef SFUD_USING_FLASH_INFO_TABLE - /* read SFDP parameters failed then using SFUD library provided static parameter */ - for (i = 0; i < sizeof(flash_chip_table) / sizeof(sfud_flash_chip); i++) { - if ((flash_chip_table[i].mf_id == flash->chip.mf_id) - && (flash_chip_table[i].type_id == flash->chip.type_id) - && (flash_chip_table[i].capacity_id == flash->chip.capacity_id)) { - flash->chip.name = flash_chip_table[i].name; - flash->chip.capacity = flash_chip_table[i].capacity; - flash->chip.write_mode = flash_chip_table[i].write_mode; - flash->chip.erase_gran = flash_chip_table[i].erase_gran; - flash->chip.erase_gran_cmd = flash_chip_table[i].erase_gran_cmd; - break; - } - } -#endif - -#ifdef SFUD_USING_SFDP - } -#endif - - } - - if (flash->chip.capacity == 0 || flash->chip.write_mode == 0 || flash->chip.erase_gran == 0 - || flash->chip.erase_gran_cmd == 0) { - SFUD_INFO("Warning: This flash device is not found or not support."); - return SFUD_ERR_NOT_FOUND; - } else { - const char *flash_mf_name = NULL; - /* find the manufacturer information */ - for (i = 0; i < sizeof(mf_table) / sizeof(sfud_mf); i++) { - if (mf_table[i].id == flash->chip.mf_id) { - flash_mf_name = mf_table[i].name; - break; - } - } - /* print manufacturer and flash chip name */ - if (flash_mf_name && flash->chip.name) { - SFUD_INFO("Find a %s %s flash chip. Size is %ld bytes.", flash_mf_name, flash->chip.name, - flash->chip.capacity); - } else if (flash_mf_name) { - SFUD_INFO("Find a %s flash chip. Size is %ld bytes.", flash_mf_name, flash->chip.capacity); - } else { - SFUD_INFO("Find a flash chip. Size is %ld bytes.", flash->chip.capacity); - } - } - - /* reset flash device */ - result = reset(flash); - if (result != SFUD_SUCCESS) { - return result; - } - - /* I found when the flash write mode is supported AAI mode. The flash all blocks is protected, - * so need change the flash status to unprotected before write and erase operate. */ - if (flash->chip.write_mode & SFUD_WM_AAI) { - result = sfud_write_status(flash, true, 0x00); - if (result != SFUD_SUCCESS) { - return result; - } - } - - /* if the flash is large than 16MB (256Mb) then enter in 4-Byte addressing mode */ - if (flash->chip.capacity > (1L << 24)) { - result = set_4_byte_address_mode(flash, true); - } else { - flash->addr_in_4_byte = false; - } - - return result; -} - -/** - * software initialize - * - * @param flash flash device - * - * @return result - */ -static sfud_err software_init(const sfud_flash *flash) { - sfud_err result = SFUD_SUCCESS; - - SFUD_ASSERT(flash); - - return result; -} - -/** - * read flash data - * - * @param flash flash device - * @param addr start address - * @param size read size - * @param data read data pointer - * - * @return result - */ -sfud_err sfud_read(const sfud_flash *flash, uint32_t addr, size_t size, uint8_t *data) { - sfud_err result = SFUD_SUCCESS; - const sfud_spi *spi = &flash->spi; - uint8_t cmd_data[5], cmd_size; - - SFUD_ASSERT(flash); - SFUD_ASSERT(data); - /* must be call this function after initialize OK */ - SFUD_ASSERT(flash->init_ok); - /* check the flash address bound */ - if (addr + size > flash->chip.capacity) { - SFUD_INFO("Error: Flash address is out of bound."); - return SFUD_ERR_ADDR_OUT_OF_BOUND; - } - /* lock SPI */ - if (spi->lock) { - spi->lock(spi); - } - - result = wait_busy(flash); - - if (result == SFUD_SUCCESS) { -#ifdef SFUD_USING_QSPI - if (flash->read_cmd_format.instruction != SFUD_CMD_READ_DATA) { - result = spi->qspi_read(spi, addr, (sfud_qspi_read_cmd_format *)&flash->read_cmd_format, data, size); - } else -#endif - { - cmd_data[0] = SFUD_CMD_READ_DATA; - make_adress_byte_array(flash, addr, &cmd_data[1]); - cmd_size = flash->addr_in_4_byte ? 5 : 4; - result = spi->wr(spi, cmd_data, cmd_size, data, size); - } - } - /* unlock SPI */ - if (spi->unlock) { - spi->unlock(spi); - } - - return result; -} - -/** - * erase all flash data - * - * @param flash flash device - * - * @return result - */ -sfud_err sfud_chip_erase(const sfud_flash *flash) { - sfud_err result = SFUD_SUCCESS; - const sfud_spi *spi = &flash->spi; - uint8_t cmd_data[4]; - - SFUD_ASSERT(flash); - /* must be call this function after initialize OK */ - SFUD_ASSERT(flash->init_ok); - /* lock SPI */ - if (spi->lock) { - spi->lock(spi); - } - - /* set the flash write enable */ - result = set_write_enabled(flash, true); - if (result != SFUD_SUCCESS) { - goto __exit; - } - - cmd_data[0] = SFUD_CMD_ERASE_CHIP; - /* dual-buffer write, like AT45DB series flash chip erase operate is different for other flash */ - if (flash->chip.write_mode & SFUD_WM_DUAL_BUFFER) { - cmd_data[1] = 0x94; - cmd_data[2] = 0x80; - cmd_data[3] = 0x9A; - result = spi->wr(spi, cmd_data, 4, NULL, 0); - } else { - result = spi->wr(spi, cmd_data, 1, NULL, 0); - } - if (result != SFUD_SUCCESS) { - SFUD_INFO("Error: Flash chip erase SPI communicate error."); - goto __exit; - } - result = wait_busy(flash); - -__exit: - /* set the flash write disable */ - set_write_enabled(flash, false); - /* unlock SPI */ - if (spi->unlock) { - spi->unlock(spi); - } - - return result; -} - -/** - * erase flash data - * - * @note It will erase align by erase granularity. - * - * @param flash flash device - * @param addr start address - * @param size erase size - * - * @return result - */ -sfud_err sfud_erase(const sfud_flash *flash, uint32_t addr, size_t size) { - extern size_t sfud_sfdp_get_suitable_eraser(const sfud_flash *flash, uint32_t addr, size_t erase_size); - - sfud_err result = SFUD_SUCCESS; - const sfud_spi *spi = &flash->spi; - uint8_t cmd_data[5], cmd_size, cur_erase_cmd; - size_t cur_erase_size; - - SFUD_ASSERT(flash); - /* must be call this function after initialize OK */ - SFUD_ASSERT(flash->init_ok); - /* check the flash address bound */ - if (addr + size > flash->chip.capacity) { - SFUD_INFO("Error: Flash address is out of bound."); - return SFUD_ERR_ADDR_OUT_OF_BOUND; - } - - if (addr == 0 && size == flash->chip.capacity) { - return sfud_chip_erase(flash); - } - - /* lock SPI */ - if (spi->lock) { - spi->lock(spi); - } - - /* loop erase operate. erase unit is erase granularity */ - while (size) { - /* if this flash is support SFDP parameter, then used SFDP parameter supplies eraser */ -#ifdef SFUD_USING_SFDP - size_t eraser_index; - if (flash->sfdp.available) { - /* get the suitable eraser for erase process from SFDP parameter */ - eraser_index = sfud_sfdp_get_suitable_eraser(flash, addr, size); - cur_erase_cmd = flash->sfdp.eraser[eraser_index].cmd; - cur_erase_size = flash->sfdp.eraser[eraser_index].size; - } else { -#else - { -#endif - cur_erase_cmd = flash->chip.erase_gran_cmd; - cur_erase_size = flash->chip.erase_gran; - } - /* set the flash write enable */ - result = set_write_enabled(flash, true); - if (result != SFUD_SUCCESS) { - goto __exit; - } - - cmd_data[0] = cur_erase_cmd; - make_adress_byte_array(flash, addr, &cmd_data[1]); - cmd_size = flash->addr_in_4_byte ? 5 : 4; - result = spi->wr(spi, cmd_data, cmd_size, NULL, 0); - if (result != SFUD_SUCCESS) { - SFUD_INFO("Error: Flash erase SPI communicate error."); - goto __exit; - } - result = wait_busy(flash); - if (result != SFUD_SUCCESS) { - goto __exit; - } - /* make erase align and calculate next erase address */ - if (addr % cur_erase_size != 0) { - if (size > cur_erase_size - (addr % cur_erase_size)) { - size -= cur_erase_size - (addr % cur_erase_size); - addr += cur_erase_size - (addr % cur_erase_size); - } else { - goto __exit; - } - } else { - if (size > cur_erase_size) { - size -= cur_erase_size; - addr += cur_erase_size; - } else { - goto __exit; - } - } - } - -__exit: - /* set the flash write disable */ - set_write_enabled(flash, false); - /* unlock SPI */ - if (spi->unlock) { - spi->unlock(spi); - } - - return result; -} - -/** - * write flash data (no erase operate) for write 1 to 256 bytes per page mode or byte write mode - * - * @param flash flash device - * @param addr start address - * @param size write size - * @param write_gran write granularity bytes, only support 1 or 256 - * @param data write data - * - * @return result - */ -static sfud_err page256_or_1_byte_write(const sfud_flash *flash, uint32_t addr, size_t size, uint16_t write_gran, - const uint8_t *data) { - sfud_err result = SFUD_SUCCESS; - const sfud_spi *spi = &flash->spi; - static uint8_t cmd_data[5 + SFUD_WRITE_MAX_PAGE_SIZE]; - uint8_t cmd_size; - size_t data_size; - - SFUD_ASSERT(flash); - /* only support 1 or 256 */ - SFUD_ASSERT(write_gran == 1 || write_gran == 256); - /* must be call this function after initialize OK */ - SFUD_ASSERT(flash->init_ok); - /* check the flash address bound */ - if (addr + size > flash->chip.capacity) { - SFUD_INFO("Error: Flash address is out of bound."); - return SFUD_ERR_ADDR_OUT_OF_BOUND; - } - /* lock SPI */ - if (spi->lock) { - spi->lock(spi); - } - - /* loop write operate. write unit is write granularity */ - while (size) { - /* set the flash write enable */ - result = set_write_enabled(flash, true); - if (result != SFUD_SUCCESS) { - goto __exit; - } - cmd_data[0] = SFUD_CMD_PAGE_PROGRAM; - make_adress_byte_array(flash, addr, &cmd_data[1]); - cmd_size = flash->addr_in_4_byte ? 5 : 4; - - /* make write align and calculate next write address */ - if (addr % write_gran != 0) { - if (size > write_gran - (addr % write_gran)) { - data_size = write_gran - (addr % write_gran); - } else { - data_size = size; - } - } else { - if (size > write_gran) { - data_size = write_gran; - } else { - data_size = size; - } - } - size -= data_size; - addr += data_size; - - memcpy(&cmd_data[cmd_size], data, data_size); - - result = spi->wr(spi, cmd_data, cmd_size + data_size, NULL, 0); - if (result != SFUD_SUCCESS) { - SFUD_INFO("Error: Flash write SPI communicate error."); - goto __exit; - } - result = wait_busy(flash); - if (result != SFUD_SUCCESS) { - goto __exit; - } - data += data_size; - } - -__exit: - /* set the flash write disable */ - set_write_enabled(flash, false); - /* unlock SPI */ - if (spi->unlock) { - spi->unlock(spi); - } - - return result; -} - -/** - * write flash data (no erase operate) for auto address increment mode - * - * If the address is odd number, it will place one 0xFF before the start of data for protect the old data. - * If the latest remain size is 1, it will append one 0xFF at the end of data for protect the old data. - * - * @param flash flash device - * @param addr start address - * @param size write size - * @param data write data - * - * @return result - */ -static sfud_err aai_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data) { - sfud_err result = SFUD_SUCCESS; - const sfud_spi *spi = &flash->spi; - uint8_t cmd_data[8], cmd_size; - bool first_write = true; - - SFUD_ASSERT(flash); - SFUD_ASSERT(flash->init_ok); - /* check the flash address bound */ - if (addr + size > flash->chip.capacity) { - SFUD_INFO("Error: Flash address is out of bound."); - return SFUD_ERR_ADDR_OUT_OF_BOUND; - } - /* lock SPI */ - if (spi->lock) { - spi->lock(spi); - } - /* The address must be even for AAI write mode. So it must write one byte first when address is odd. */ - if (addr % 2 != 0) { - result = page256_or_1_byte_write(flash, addr++, 1, 1, data++); - if (result != SFUD_SUCCESS) { - goto __exit; - } - size--; - } - /* set the flash write enable */ - result = set_write_enabled(flash, true); - if (result != SFUD_SUCCESS) { - goto __exit; - } - /* loop write operate. */ - cmd_data[0] = SFUD_CMD_AAI_WORD_PROGRAM; - while (size >= 2) { - if (first_write) { - make_adress_byte_array(flash, addr, &cmd_data[1]); - cmd_size = flash->addr_in_4_byte ? 5 : 4; - cmd_data[cmd_size] = *data; - cmd_data[cmd_size + 1] = *(data + 1); - first_write = false; - } else { - cmd_size = 1; - cmd_data[1] = *data; - cmd_data[2] = *(data + 1); - } - - result = spi->wr(spi, cmd_data, cmd_size + 2, NULL, 0); - if (result != SFUD_SUCCESS) { - SFUD_INFO("Error: Flash write SPI communicate error."); - goto __exit; - } - - result = wait_busy(flash); - if (result != SFUD_SUCCESS) { - goto __exit; - } - - size -= 2; - addr += 2; - data += 2; - } - /* set the flash write disable for exit AAI mode */ - result = set_write_enabled(flash, false); - /* write last one byte data when origin write size is odd */ - if (result == SFUD_SUCCESS && size == 1) { - result = page256_or_1_byte_write(flash, addr, 1, 1, data); - } - -__exit: - if (result != SFUD_SUCCESS) { - set_write_enabled(flash, false); - } - /* unlock SPI */ - if (spi->unlock) { - spi->unlock(spi); - } - - return result; -} - -/** - * write flash data (no erase operate) - * - * @param flash flash device - * @param addr start address - * @param size write size - * @param data write data - * - * @return result - */ -sfud_err sfud_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data) { - sfud_err result = SFUD_SUCCESS; - - if (flash->chip.write_mode & SFUD_WM_PAGE_256B) { - result = page256_or_1_byte_write(flash, addr, size, 256, data); - } else if (flash->chip.write_mode & SFUD_WM_AAI) { - result = aai_write(flash, addr, size, data); - } else if (flash->chip.write_mode & SFUD_WM_DUAL_BUFFER) { - //TODO dual-buffer write mode - } - - return result; -} - -/** - * erase and write flash data - * - * @param flash flash device - * @param addr start address - * @param size write size - * @param data write data - * - * @return result - */ -sfud_err sfud_erase_write(const sfud_flash *flash, uint32_t addr, size_t size, const uint8_t *data) { - sfud_err result = SFUD_SUCCESS; - - result = sfud_erase(flash, addr, size); - - if (result == SFUD_SUCCESS) { - result = sfud_write(flash, addr, size, data); - } - - return result; -} - -static sfud_err reset(const sfud_flash *flash) { - sfud_err result = SFUD_SUCCESS; - const sfud_spi *spi = &flash->spi; - uint8_t cmd_data[2]; - - SFUD_ASSERT(flash); - - cmd_data[0] = SFUD_CMD_ENABLE_RESET; - result = spi->wr(spi, cmd_data, 1, NULL, 0); - if (result == SFUD_SUCCESS) { - result = wait_busy(flash); - } else { - SFUD_INFO("Error: Flash device reset failed."); - return result; - } - - cmd_data[1] = SFUD_CMD_RESET; - result = spi->wr(spi, &cmd_data[1], 1, NULL, 0); - - if (result == SFUD_SUCCESS) { - result = wait_busy(flash); - } - - if (result == SFUD_SUCCESS) { - SFUD_DEBUG("Flash device reset success."); - } else { - SFUD_INFO("Error: Flash device reset failed."); - } - - return result; -} - -static sfud_err read_jedec_id(sfud_flash *flash) { - sfud_err result = SFUD_SUCCESS; - const sfud_spi *spi = &flash->spi; - uint8_t cmd_data[1], recv_data[3]; - - SFUD_ASSERT(flash); - - cmd_data[0] = SFUD_CMD_JEDEC_ID; - result = spi->wr(spi, cmd_data, sizeof(cmd_data), recv_data, sizeof(recv_data)); - if (result == SFUD_SUCCESS) { - flash->chip.mf_id = recv_data[0]; - flash->chip.type_id = recv_data[1]; - flash->chip.capacity_id = recv_data[2]; - SFUD_DEBUG("The flash device manufacturer ID is 0x%02X, memory type ID is 0x%02X, capacity ID is 0x%02X.", - flash->chip.mf_id, flash->chip.type_id, flash->chip.capacity_id); - } else { - SFUD_INFO("Error: Read flash device JEDEC ID error."); - } - - return result; -} - -/** - * set the flash write enable or write disable - * - * @param flash flash device - * @param enabled true: enable false: disable - * - * @return result - */ -static sfud_err set_write_enabled(const sfud_flash *flash, bool enabled) { - sfud_err result = SFUD_SUCCESS; - uint8_t cmd, register_status; - - SFUD_ASSERT(flash); - - if (enabled) { - cmd = SFUD_CMD_WRITE_ENABLE; - } else { - cmd = SFUD_CMD_WRITE_DISABLE; - } - - result = flash->spi.wr(&flash->spi, &cmd, 1, NULL, 0); - - if (result == SFUD_SUCCESS) { - result = sfud_read_status(flash, ®ister_status); - } - - if (result == SFUD_SUCCESS) { - if (enabled && (register_status & SFUD_STATUS_REGISTER_WEL) == 0) { - SFUD_INFO("Error: Can't enable write status."); - return SFUD_ERR_WRITE; - } else if (!enabled && (register_status & SFUD_STATUS_REGISTER_WEL) == 1) { - SFUD_INFO("Error: Can't disable write status."); - return SFUD_ERR_WRITE; - } - } - - return result; -} - -/** - * enable or disable 4-Byte addressing for flash - * - * @note The 4-Byte addressing just supported for the flash capacity which is large then 16MB (256Mb). - * - * @param flash flash device - * @param enabled true: enable false: disable - * - * @return result - */ -static sfud_err set_4_byte_address_mode(sfud_flash *flash, bool enabled) { - sfud_err result = SFUD_SUCCESS; - uint8_t cmd; - - SFUD_ASSERT(flash); - - /* set the flash write enable */ - result = set_write_enabled(flash, true); - if (result != SFUD_SUCCESS) { - return result; - } - - if (enabled) { - cmd = SFUD_CMD_ENTER_4B_ADDRESS_MODE; - } else { - cmd = SFUD_CMD_EXIT_4B_ADDRESS_MODE; - } - - result = flash->spi.wr(&flash->spi, &cmd, 1, NULL, 0); - - if (result == SFUD_SUCCESS) { - flash->addr_in_4_byte = enabled ? true : false; - SFUD_DEBUG("%s 4-Byte addressing mode success.", enabled ? "Enter" : "Exit"); - } else { - SFUD_INFO("Error: %s 4-Byte addressing mode failed.", enabled ? "Enter" : "Exit"); - } - - return result; -} - -/** - * read flash register status - * - * @param flash flash device - * @param status register status - * - * @return result - */ -sfud_err sfud_read_status(const sfud_flash *flash, uint8_t *status) { - uint8_t cmd = SFUD_CMD_READ_STATUS_REGISTER; - - SFUD_ASSERT(flash); - SFUD_ASSERT(status); - - return flash->spi.wr(&flash->spi, &cmd, 1, status, 1); -} - -static sfud_err wait_busy(const sfud_flash *flash) { - sfud_err result = SFUD_SUCCESS; - uint8_t status; - size_t retry_times = flash->retry.times; - - SFUD_ASSERT(flash); - - while (true) { - result = sfud_read_status(flash, &status); - if (result == SFUD_SUCCESS && ((status & SFUD_STATUS_REGISTER_BUSY)) == 0) { - break; - } - /* retry counts */ - SFUD_RETRY_PROCESS(flash->retry.delay, retry_times, result); - } - - if (result != SFUD_SUCCESS || ((status & SFUD_STATUS_REGISTER_BUSY)) != 0) { - SFUD_INFO("Error: Flash wait busy has an error."); - } - - return result; -} - -static void make_adress_byte_array(const sfud_flash *flash, uint32_t addr, uint8_t *array) { - uint8_t len, i; - - SFUD_ASSERT(flash); - SFUD_ASSERT(array); - - len = flash->addr_in_4_byte ? 4 : 3; - - for (i = 0; i < len; i++) { - array[i] = (addr >> ((len - (i + 1)) * 8)) & 0xFF; - } -} - -/** - * write status register - * - * @param flash flash device - * @param is_volatile true: volatile mode, false: non-volatile mode - * @param status register status - * - * @return result - */ -sfud_err sfud_write_status(const sfud_flash *flash, bool is_volatile, uint8_t status) { - sfud_err result = SFUD_SUCCESS; - const sfud_spi *spi = &flash->spi; - uint8_t cmd_data[2]; - - SFUD_ASSERT(flash); - - if (is_volatile) { - cmd_data[0] = SFUD_VOLATILE_SR_WRITE_ENABLE; - result = spi->wr(spi, cmd_data, 1, NULL, 0); - } else { - result = set_write_enabled(flash, true); - } - - if (result == SFUD_SUCCESS) { - cmd_data[0] = SFUD_CMD_WRITE_STATUS_REGISTER; - cmd_data[1] = status; - result = spi->wr(spi, cmd_data, 2, NULL, 0); - } - - if (result != SFUD_SUCCESS) { - SFUD_INFO("Error: Write_status register failed."); - } - - return result; -} diff --git a/IoTGateWay/components/drivers/spi/sfud/src/sfud_sfdp.c b/IoTGateWay/components/drivers/spi/sfud/src/sfud_sfdp.c deleted file mode 100644 index 0c81e073e64fd..0000000000000 --- a/IoTGateWay/components/drivers/spi/sfud/src/sfud_sfdp.c +++ /dev/null @@ -1,387 +0,0 @@ -/* - * This file is part of the Serial Flash Universal Driver Library. - * - * Copyright (c) 2016, Armink, - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * 'Software'), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY - * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - * Function: Analyze the SFDP (Serial Flash Discoverable Parameters) which from JESD216/A/B (V1.X) standard. - * JESD216 (V1.0) document: http://www.jedec.org/sites/default/files/docs/JESD216.pdf - * JESD216A (V1.5) document: http://www.jedec.org/sites/default/files/docs/JESD216A.pdf - * JESD216B (V1.6) document: http://www.jedec.org/sites/default/files/docs/JESD216B.pdf - * - * Created on: 2016-05-26 - */ - -#include "../inc/sfud.h" - -/** - * JEDEC Standard JESD216 Terms and definitions: - * - * DWORD: Four consecutive 8-bit bytes used as the basic 32-bit building block for headers and parameter tables. - * - * Sector: The minimum granularity - size and alignment - of an area that can be erased in the data array - * of a flash memory device. Different areas within the address range of the data array may have a different - * minimum erase granularity (sector size). - */ - -#ifdef SFUD_USING_SFDP - -/* support maximum SFDP major revision by driver */ -#define SUPPORT_MAX_SFDP_MAJOR_REV 1 -/* the JEDEC basic flash parameter table length is 9 DWORDs (288-bit) on JESD216 (V1.0) initial release standard */ -#define BASIC_TABLE_LEN 9 -/* the smallest eraser in SFDP eraser table */ -#define SMALLEST_ERASER_INDEX 0 -/** - * SFDP parameter header structure - */ -typedef struct { - uint8_t id; /**< Parameter ID LSB */ - uint8_t minor_rev; /**< Parameter minor revision */ - uint8_t major_rev; /**< Parameter major revision */ - uint8_t len; /**< Parameter table length(in double words) */ - uint32_t ptp; /**< Parameter table 24bit pointer (byte address) */ -} sfdp_para_header; - -static sfud_err read_sfdp_data(const sfud_flash *flash, uint32_t addr, uint8_t *read_buf, size_t size); -static bool read_sfdp_header(sfud_flash *flash); -static bool read_basic_header(const sfud_flash *flash, sfdp_para_header *basic_header); -static bool read_basic_table(sfud_flash *flash, sfdp_para_header *basic_header); - -/* ../port/sfup_port.c */ -extern void sfud_log_debug(const char *file, const long line, const char *format, ...); -extern void sfud_log_info(const char *format, ...); - -/** - * Read SFDP parameter information - * - * @param flash flash device - * - * @return true: read OK - */ -bool sfud_read_sfdp(sfud_flash *flash) { - SFUD_ASSERT(flash); - - /* JEDEC basic flash parameter header */ - sfdp_para_header basic_header; - if (read_sfdp_header(flash) && read_basic_header(flash, &basic_header)) { - return read_basic_table(flash, &basic_header); - } else { - SFUD_INFO("Warning: Read SFDP parameter header information failed. The %s is not support JEDEC SFDP.", flash->name); - return false; - } -} - -/** - * Read SFDP parameter header - * - * @param flash flash device - * - * @return true: read OK - */ -static bool read_sfdp_header(sfud_flash *flash) { - sfud_sfdp *sfdp = &flash->sfdp; - /* The SFDP header is located at address 000000h of the SFDP data structure. - * It identifies the SFDP Signature, the number of parameter headers, and the SFDP revision numbers. */ - /* sfdp parameter header address */ - uint32_t header_addr = 0; - /* each parameter header being 2 DWORDs (64-bit) */ - uint8_t header[2 * 4] = { 0 }; - - SFUD_ASSERT(flash); - - sfdp->available = false; - /* read SFDP header */ - if (read_sfdp_data(flash, header_addr, header, sizeof(header)) != SFUD_SUCCESS) { - SFUD_INFO("Error: Can't read SFDP header."); - return false; - } - /* check SFDP header */ - if (!(header[0] == 'S' && - header[1] == 'F' && - header[2] == 'D' && - header[3] == 'P')) { - SFUD_DEBUG("Error: Check SFDP signature error. It's must be 50444653h('S' 'F' 'D' 'P')."); - return false; - } - sfdp->minor_rev = header[4]; - sfdp->major_rev = header[5]; - if (sfdp->major_rev > SUPPORT_MAX_SFDP_MAJOR_REV) { - SFUD_INFO("Error: This reversion(V%d.%d) SFDP is not supported.", sfdp->major_rev, sfdp->minor_rev); - return false; - } - SFUD_DEBUG("Check SFDP header is OK. The reversion is V%d.%d, NPN is %d.", sfdp->major_rev, sfdp->minor_rev, - header[6]); - - return true; -} - -/** - * Read JEDEC basic parameter header - * - * @param flash flash device - * - * @return true: read OK - */ -static bool read_basic_header(const sfud_flash *flash, sfdp_para_header *basic_header) { - /* The basic parameter header is mandatory, is defined by this standard, and starts at byte offset 08h. */ - uint32_t header_addr = 8; - /* each parameter header being 2 DWORDs (64-bit) */ - uint8_t header[2 * 4] = { 0 }; - - SFUD_ASSERT(flash); - SFUD_ASSERT(basic_header); - - /* read JEDEC basic flash parameter header */ - if (read_sfdp_data(flash, header_addr, header, sizeof(header)) != SFUD_SUCCESS) { - SFUD_INFO("Error: Can't read JEDEC basic flash parameter header."); - return false; - } - basic_header->id = header[0]; - basic_header->minor_rev = header[1]; - basic_header->major_rev = header[2]; - basic_header->len = header[3]; - basic_header->ptp = (long)header[4] | (long)header[5] << 8 | (long)header[6] << 16; - /* check JEDEC basic flash parameter header */ - if (basic_header->major_rev > SUPPORT_MAX_SFDP_MAJOR_REV) { - SFUD_INFO("Error: This reversion(V%d.%d) JEDEC basic flash parameter header is not supported.", - basic_header->major_rev, basic_header->minor_rev); - return false; - } - if (basic_header->len < BASIC_TABLE_LEN) { - SFUD_INFO("Error: The JEDEC basic flash parameter table length (now is %d) error.", basic_header->len); - return false; - } - SFUD_DEBUG("Check JEDEC basic flash parameter header is OK. The table id is %d, reversion is V%d.%d," - " length is %d, parameter table pointer is 0x%06lX.", basic_header->id, basic_header->major_rev, - basic_header->minor_rev, basic_header->len, basic_header->ptp); - - return true; -} - -/** - * Read JEDEC basic parameter table - * - * @param flash flash device - * - * @return true: read OK - */ -static bool read_basic_table(sfud_flash *flash, sfdp_para_header *basic_header) { - sfud_sfdp *sfdp = &flash->sfdp; - /* parameter table address */ - uint32_t table_addr = basic_header->ptp; - /* parameter table */ - uint8_t table[BASIC_TABLE_LEN * 4] = { 0 }, i, j; - - SFUD_ASSERT(flash); - SFUD_ASSERT(basic_header); - - /* read JEDEC basic flash parameter table */ - if (read_sfdp_data(flash, table_addr, table, sizeof(table)) != SFUD_SUCCESS) { - SFUD_INFO("Warning: Can't read JEDEC basic flash parameter table."); - return false; - } - /* print JEDEC basic flash parameter table info */ - SFUD_DEBUG("JEDEC basic flash parameter table info:"); - SFUD_DEBUG("MSB-LSB 3 2 1 0"); - for (i = 0; i < BASIC_TABLE_LEN; i++) { - SFUD_DEBUG("[%04d] 0x%02X 0x%02X 0x%02X 0x%02X", i + 1, table[i * 4 + 3], table[i * 4 + 2], table[i * 4 + 1], - table[i * 4]); - } - - /* get block/sector 4 KB erase supported and command */ - sfdp->erase_4k_cmd = table[1]; - switch (table[0] & 0x03) { - case 1: - sfdp->erase_4k = true; - SFUD_DEBUG("4 KB Erase is supported throughout the device. Command is 0x%02X.", sfdp->erase_4k_cmd); - break; - case 3: - sfdp->erase_4k = false; - SFUD_DEBUG("Uniform 4 KB erase is unavailable for this device."); - break; - default: - SFUD_INFO("Error: Uniform 4 KB erase supported information error."); - return false; - } - /* get write granularity */ - //TODO ĿǰΪ 1.0 ṩķʽ֧ V1.5 ϵķʽȡ page size - switch ((table[0] & (0x01 << 2)) >> 2) { - case 0: - sfdp->write_gran = 1; - SFUD_DEBUG("Write granularity is 1 byte."); - break; - case 1: - sfdp->write_gran = 256; - SFUD_DEBUG("Write granularity is 64 bytes or larger."); - break; - } - /* volatile status register block protect bits */ - switch ((table[0] & (0x01 << 3)) >> 3) { - case 0: - /* Block Protect bits in device's status register are solely non-volatile or may be - * programmed either as volatile using the 50h instruction for write enable or non-volatile - * using the 06h instruction for write enable. - */ - sfdp->sr_is_non_vola = true; - SFUD_DEBUG("Target flash status register is non-volatile."); - break; - case 1: - /* block protect bits in device's status register are solely volatile. */ - sfdp->sr_is_non_vola = false; - SFUD_DEBUG("Block Protect bits in device's status register are solely volatile."); - /* write enable instruction select for writing to volatile status register */ - switch ((table[0] & (0x01 << 4)) >> 4) { - case 0: - sfdp->vola_sr_we_cmd = SFUD_VOLATILE_SR_WRITE_ENABLE; - SFUD_DEBUG("Flash device requires instruction 50h as the write enable prior " - "to performing a volatile write to the status register."); - break; - case 1: - sfdp->vola_sr_we_cmd = SFUD_CMD_WRITE_ENABLE; - SFUD_DEBUG("Flash device requires instruction 06h as the write enable prior " - "to performing a volatile write to the status register."); - break; - } - break; - } - /* get address bytes, number of bytes used in addressing flash array read, write and erase. */ - switch ((table[2] & (0x03 << 1)) >> 1) { - case 0: - sfdp->addr_3_byte = true; - sfdp->addr_4_byte = false; - SFUD_DEBUG("3-Byte only addressing."); - break; - case 1: - sfdp->addr_3_byte = true; - sfdp->addr_4_byte = true; - SFUD_DEBUG("3- or 4-Byte addressing."); - break; - case 2: - sfdp->addr_3_byte = false; - sfdp->addr_4_byte = true; - SFUD_DEBUG("4-Byte only addressing."); - break; - default: - sfdp->addr_3_byte = false; - sfdp->addr_4_byte = false; - SFUD_INFO("Error: Read address bytes error!"); - return false; - } - /* get flash memory capacity */ - uint32_t table2_temp = ((long)table[7] << 24) | ((long)table[6] << 16) | ((long)table[5] << 8) | (long)table[4]; - switch ((table[7] & (0x01 << 7)) >> 7) { - case 0: - sfdp->capacity = 1 + (table2_temp >> 3); - break; - case 1: - table2_temp &= 0x7FFFFFFF; - if (table2_temp > sizeof(sfdp->capacity) * 8 + 3) { - sfdp->capacity = 0; - SFUD_INFO("Error: The flash capacity is grater than 32 Gb/ 4 GB! Not Supported."); - return false; - } - sfdp->capacity = 1L << (table2_temp - 3); - break; - } - SFUD_DEBUG("Capacity is %ld Bytes.", sfdp->capacity); - /* get erase size and erase command */ - for (i = 0, j = 0; i < SFUD_SFDP_ERASE_TYPE_MAX_NUM; i++) { - if (table[28 + 2 * i] != 0x00) { - sfdp->eraser[j].size = 1L << table[28 + 2 * i]; - sfdp->eraser[j].cmd = table[28 + 2 * i + 1]; - SFUD_DEBUG("Flash device supports %ldKB block erase. Command is 0x%02X.", sfdp->eraser[j].size / 1024, - sfdp->eraser[j].cmd); - j++; - } - } - /* sort the eraser size from small to large */ - for (i = 0, j = 0; i < SFUD_SFDP_ERASE_TYPE_MAX_NUM; i++) { - if (sfdp->eraser[i].size) { - for (j = i + 1; j < SFUD_SFDP_ERASE_TYPE_MAX_NUM; j++) { - if (sfdp->eraser[j].size != 0 && sfdp->eraser[i].size > sfdp->eraser[j].size) { - /* swap the small eraser */ - uint32_t temp_size = sfdp->eraser[i].size; - uint8_t temp_cmd = sfdp->eraser[i].cmd; - sfdp->eraser[i].size = sfdp->eraser[j].size; - sfdp->eraser[i].cmd = sfdp->eraser[j].cmd; - sfdp->eraser[j].size = temp_size; - sfdp->eraser[j].cmd = temp_cmd; - } - } - } - } - - sfdp->available = true; - return true; -} - -static sfud_err read_sfdp_data(const sfud_flash *flash, uint32_t addr, uint8_t *read_buf, size_t size) { - uint8_t cmd[] = { - SFUD_CMD_READ_SFDP_REGISTER, - (addr >> 16) & 0xFF, - (addr >> 8) & 0xFF, - (addr >> 0) & 0xFF, - SFUD_DUMMY_DATA, - }; - - SFUD_ASSERT(flash); - SFUD_ASSERT(addr < 1L << 24); - SFUD_ASSERT(read_buf); - SFUD_ASSERT(flash->spi.wr); - - return flash->spi.wr(&flash->spi, cmd, sizeof(cmd), read_buf, size); -} - -/** - * get the most suitable eraser for erase process from SFDP parameter - * - * @param flash flash device - * @param addr start address - * @param erase_size will be erased size - * - * @return the eraser index of SFDP eraser table @see sfud_sfdp.eraser[] - */ -size_t sfud_sfdp_get_suitable_eraser(const sfud_flash *flash, uint32_t addr, size_t erase_size) { - size_t index = SMALLEST_ERASER_INDEX, i; - /* only used when flash supported SFDP */ - SFUD_ASSERT(flash->sfdp.available); - /* the address isn't align by smallest eraser's size, then use the smallest eraser */ - if (addr % flash->sfdp.eraser[SMALLEST_ERASER_INDEX].size) { - return SMALLEST_ERASER_INDEX; - } - /* Find the suitable eraser. - * The largest size eraser is at the end of eraser table. - * In order to decrease erase command counts, so the find process is from the end of eraser table. */ - for (i = SFUD_SFDP_ERASE_TYPE_MAX_NUM - 1;; i--) { - if ((flash->sfdp.eraser[i].size != 0) && (erase_size >= flash->sfdp.eraser[i].size) - && (addr % flash->sfdp.eraser[i].size == 0)) { - index = i; - break; - } - if (i == SMALLEST_ERASER_INDEX) { - break; - } - } - return index; -} - -#endif /* SFUD_USING_SFDP */ diff --git a/IoTGateWay/components/drivers/spi/spi_core.c b/IoTGateWay/components/drivers/spi/spi_core.c deleted file mode 100644 index 64b0d2e496448..0000000000000 --- a/IoTGateWay/components/drivers/spi/spi_core.c +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2012-01-08 bernard first version. - * 2012-02-03 bernard add const attribute to the ops. - * 2012-05-15 dzzxzz fixed the return value in attach_device. - * 2012-05-18 bernard Changed SPI message to message list. - * Added take/release SPI device/bus interface. - * 2012-09-28 aozima fixed rt_spi_release_bus assert error. - */ - -#include - -extern rt_err_t rt_spi_bus_device_init(struct rt_spi_bus *bus, const char *name); -extern rt_err_t rt_spidev_device_init(struct rt_spi_device *dev, const char *name); - -rt_err_t rt_spi_bus_register(struct rt_spi_bus *bus, - const char *name, - const struct rt_spi_ops *ops) -{ - rt_err_t result; - - result = rt_spi_bus_device_init(bus, name); - if (result != RT_EOK) - return result; - - /* initialize mutex lock */ - rt_mutex_init(&(bus->lock), name, RT_IPC_FLAG_FIFO); - /* set ops */ - bus->ops = ops; - /* initialize owner */ - bus->owner = RT_NULL; - /* set bus mode */ - bus->mode = RT_SPI_BUS_MODE_SPI; - - return RT_EOK; -} - -rt_err_t rt_spi_bus_attach_device(struct rt_spi_device *device, - const char *name, - const char *bus_name, - void *user_data) -{ - rt_err_t result; - rt_device_t bus; - - /* get physical spi bus */ - bus = rt_device_find(bus_name); - if (bus != RT_NULL && bus->type == RT_Device_Class_SPIBUS) - { - device->bus = (struct rt_spi_bus *)bus; - - /* initialize spidev device */ - result = rt_spidev_device_init(device, name); - if (result != RT_EOK) - return result; - - rt_memset(&device->config, 0, sizeof(device->config)); - device->parent.user_data = user_data; - - return RT_EOK; - } - - /* not found the host bus */ - return -RT_ERROR; -} - -rt_err_t rt_spi_configure(struct rt_spi_device *device, - struct rt_spi_configuration *cfg) -{ - rt_err_t result; - - RT_ASSERT(device != RT_NULL); - - /* set configuration */ - device->config.data_width = cfg->data_width; - device->config.mode = cfg->mode & RT_SPI_MODE_MASK ; - device->config.max_hz = cfg->max_hz ; - - if (device->bus != RT_NULL) - { - result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER); - if (result == RT_EOK) - { - if (device->bus->owner == device) - { - device->bus->ops->configure(device, &device->config); - } - - /* release lock */ - rt_mutex_release(&(device->bus->lock)); - } - } - - return RT_EOK; -} - -rt_err_t rt_spi_send_then_send(struct rt_spi_device *device, - const void *send_buf1, - rt_size_t send_length1, - const void *send_buf2, - rt_size_t send_length2) -{ - rt_err_t result; - struct rt_spi_message message; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - - result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER); - if (result == RT_EOK) - { - if (device->bus->owner != device) - { - /* not the same owner as current, re-configure SPI bus */ - result = device->bus->ops->configure(device, &device->config); - if (result == RT_EOK) - { - /* set SPI bus owner */ - device->bus->owner = device; - } - else - { - /* configure SPI bus failed */ - result = -RT_EIO; - goto __exit; - } - } - - /* send data1 */ - message.send_buf = send_buf1; - message.recv_buf = RT_NULL; - message.length = send_length1; - message.cs_take = 1; - message.cs_release = 0; - message.next = RT_NULL; - - result = device->bus->ops->xfer(device, &message); - if (result == 0) - { - result = -RT_EIO; - goto __exit; - } - - /* send data2 */ - message.send_buf = send_buf2; - message.recv_buf = RT_NULL; - message.length = send_length2; - message.cs_take = 0; - message.cs_release = 1; - message.next = RT_NULL; - - result = device->bus->ops->xfer(device, &message); - if (result == 0) - { - result = -RT_EIO; - goto __exit; - } - - result = RT_EOK; - } - else - { - return -RT_EIO; - } - -__exit: - rt_mutex_release(&(device->bus->lock)); - - return result; -} - -rt_err_t rt_spi_send_then_recv(struct rt_spi_device *device, - const void *send_buf, - rt_size_t send_length, - void *recv_buf, - rt_size_t recv_length) -{ - rt_err_t result; - struct rt_spi_message message; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - - result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER); - if (result == RT_EOK) - { - if (device->bus->owner != device) - { - /* not the same owner as current, re-configure SPI bus */ - result = device->bus->ops->configure(device, &device->config); - if (result == RT_EOK) - { - /* set SPI bus owner */ - device->bus->owner = device; - } - else - { - /* configure SPI bus failed */ - result = -RT_EIO; - goto __exit; - } - } - - /* send data */ - message.send_buf = send_buf; - message.recv_buf = RT_NULL; - message.length = send_length; - message.cs_take = 1; - message.cs_release = 0; - message.next = RT_NULL; - - result = device->bus->ops->xfer(device, &message); - if (result == 0) - { - result = -RT_EIO; - goto __exit; - } - - /* recv data */ - message.send_buf = RT_NULL; - message.recv_buf = recv_buf; - message.length = recv_length; - message.cs_take = 0; - message.cs_release = 1; - message.next = RT_NULL; - - result = device->bus->ops->xfer(device, &message); - if (result == 0) - { - result = -RT_EIO; - goto __exit; - } - - result = RT_EOK; - } - else - { - return -RT_EIO; - } - -__exit: - rt_mutex_release(&(device->bus->lock)); - - return result; -} - -rt_size_t rt_spi_transfer(struct rt_spi_device *device, - const void *send_buf, - void *recv_buf, - rt_size_t length) -{ - rt_err_t result; - struct rt_spi_message message; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - - result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER); - if (result == RT_EOK) - { - if (device->bus->owner != device) - { - /* not the same owner as current, re-configure SPI bus */ - result = device->bus->ops->configure(device, &device->config); - if (result == RT_EOK) - { - /* set SPI bus owner */ - device->bus->owner = device; - } - else - { - /* configure SPI bus failed */ - rt_set_errno(-RT_EIO); - result = 0; - goto __exit; - } - } - - /* initial message */ - message.send_buf = send_buf; - message.recv_buf = recv_buf; - message.length = length; - message.cs_take = 1; - message.cs_release = 1; - message.next = RT_NULL; - - /* transfer message */ - result = device->bus->ops->xfer(device, &message); - if (result == 0) - { - rt_set_errno(-RT_EIO); - goto __exit; - } - } - else - { - rt_set_errno(-RT_EIO); - - return 0; - } - -__exit: - rt_mutex_release(&(device->bus->lock)); - - return result; -} - -struct rt_spi_message *rt_spi_transfer_message(struct rt_spi_device *device, - struct rt_spi_message *message) -{ - rt_err_t result; - struct rt_spi_message *index; - - RT_ASSERT(device != RT_NULL); - - /* get first message */ - index = message; - if (index == RT_NULL) - return index; - - result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER); - if (result != RT_EOK) - { - rt_set_errno(-RT_EBUSY); - - return index; - } - - /* reset errno */ - rt_set_errno(RT_EOK); - - /* configure SPI bus */ - if (device->bus->owner != device) - { - /* not the same owner as current, re-configure SPI bus */ - result = device->bus->ops->configure(device, &device->config); - if (result == RT_EOK) - { - /* set SPI bus owner */ - device->bus->owner = device; - } - else - { - /* configure SPI bus failed */ - rt_set_errno(-RT_EIO); - goto __exit; - } - } - - /* transmit each SPI message */ - while (index != RT_NULL) - { - /* transmit SPI message */ - result = device->bus->ops->xfer(device, index); - if (result == 0) - { - rt_set_errno(-RT_EIO); - break; - } - - index = index->next; - } - -__exit: - /* release bus lock */ - rt_mutex_release(&(device->bus->lock)); - - return index; -} - -rt_err_t rt_spi_take_bus(struct rt_spi_device *device) -{ - rt_err_t result = RT_EOK; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - - result = rt_mutex_take(&(device->bus->lock), RT_WAITING_FOREVER); - if (result != RT_EOK) - { - rt_set_errno(-RT_EBUSY); - - return -RT_EBUSY; - } - - /* reset errno */ - rt_set_errno(RT_EOK); - - /* configure SPI bus */ - if (device->bus->owner != device) - { - /* not the same owner as current, re-configure SPI bus */ - result = device->bus->ops->configure(device, &device->config); - if (result == RT_EOK) - { - /* set SPI bus owner */ - device->bus->owner = device; - } - else - { - /* configure SPI bus failed */ - rt_set_errno(-RT_EIO); - /* release lock */ - rt_mutex_release(&(device->bus->lock)); - - return -RT_EIO; - } - } - - return result; -} - -rt_err_t rt_spi_release_bus(struct rt_spi_device *device) -{ - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - RT_ASSERT(device->bus->owner == device); - - /* release lock */ - rt_mutex_release(&(device->bus->lock)); - - return RT_EOK; -} - -rt_err_t rt_spi_take(struct rt_spi_device *device) -{ - rt_err_t result; - struct rt_spi_message message; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - - rt_memset(&message, 0, sizeof(message)); - message.cs_take = 1; - - result = device->bus->ops->xfer(device, &message); - - return result; -} - -rt_err_t rt_spi_release(struct rt_spi_device *device) -{ - rt_err_t result; - struct rt_spi_message message; - - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - - rt_memset(&message, 0, sizeof(message)); - message.cs_release = 1; - - result = device->bus->ops->xfer(device, &message); - - return result; -} diff --git a/IoTGateWay/components/drivers/spi/spi_dev.c b/IoTGateWay/components/drivers/spi/spi_dev.c deleted file mode 100644 index e334e7aeb56d6..0000000000000 --- a/IoTGateWay/components/drivers/spi/spi_dev.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - */ - -#include -#include - -/* SPI bus device interface, compatible with RT-Thread 0.3.x/1.0.x */ -static rt_size_t _spi_bus_device_read(rt_device_t dev, - rt_off_t pos, - void *buffer, - rt_size_t size) -{ - struct rt_spi_bus *bus; - - bus = (struct rt_spi_bus *)dev; - RT_ASSERT(bus != RT_NULL); - RT_ASSERT(bus->owner != RT_NULL); - - return rt_spi_transfer(bus->owner, RT_NULL, buffer, size); -} - -static rt_size_t _spi_bus_device_write(rt_device_t dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) -{ - struct rt_spi_bus *bus; - - bus = (struct rt_spi_bus *)dev; - RT_ASSERT(bus != RT_NULL); - RT_ASSERT(bus->owner != RT_NULL); - - return rt_spi_transfer(bus->owner, buffer, RT_NULL, size); -} - -static rt_err_t _spi_bus_device_control(rt_device_t dev, - int cmd, - void *args) -{ - /* TODO: add control command handle */ - switch (cmd) - { - case 0: /* set device */ - break; - case 1: - break; - } - - return RT_EOK; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops spi_bus_ops = -{ - RT_NULL, - RT_NULL, - RT_NULL, - _spi_bus_device_read, - _spi_bus_device_write, - _spi_bus_device_control -}; -#endif - -rt_err_t rt_spi_bus_device_init(struct rt_spi_bus *bus, const char *name) -{ - struct rt_device *device; - RT_ASSERT(bus != RT_NULL); - - device = &bus->parent; - - /* set device type */ - device->type = RT_Device_Class_SPIBUS; - /* initialize device interface */ -#ifdef RT_USING_DEVICE_OPS - device->ops = &spi_bus_ops; -#else - device->init = RT_NULL; - device->open = RT_NULL; - device->close = RT_NULL; - device->read = _spi_bus_device_read; - device->write = _spi_bus_device_write; - device->control = _spi_bus_device_control; -#endif - - /* register to device manager */ - return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR); -} - -/* SPI Dev device interface, compatible with RT-Thread 0.3.x/1.0.x */ -static rt_size_t _spidev_device_read(rt_device_t dev, - rt_off_t pos, - void *buffer, - rt_size_t size) -{ - struct rt_spi_device *device; - - device = (struct rt_spi_device *)dev; - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - - return rt_spi_transfer(device, RT_NULL, buffer, size); -} - -static rt_size_t _spidev_device_write(rt_device_t dev, - rt_off_t pos, - const void *buffer, - rt_size_t size) -{ - struct rt_spi_device *device; - - device = (struct rt_spi_device *)dev; - RT_ASSERT(device != RT_NULL); - RT_ASSERT(device->bus != RT_NULL); - - return rt_spi_transfer(device, buffer, RT_NULL, size); -} - -static rt_err_t _spidev_device_control(rt_device_t dev, - int cmd, - void *args) -{ - switch (cmd) - { - case 0: /* set device */ - break; - case 1: - break; - } - - return RT_EOK; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops spi_device_ops = -{ - RT_NULL, - RT_NULL, - RT_NULL, - _spidev_device_read, - _spidev_device_write, - _spidev_device_control -}; -#endif - -rt_err_t rt_spidev_device_init(struct rt_spi_device *dev, const char *name) -{ - struct rt_device *device; - RT_ASSERT(dev != RT_NULL); - - device = &(dev->parent); - - /* set device type */ - device->type = RT_Device_Class_SPIDevice; -#ifdef RT_USING_DEVICE_OPS - device->ops = &spi_device_ops; -#else - device->init = RT_NULL; - device->open = RT_NULL; - device->close = RT_NULL; - device->read = _spidev_device_read; - device->write = _spidev_device_write; - device->control = _spidev_device_control; -#endif - - /* register to device manager */ - return rt_device_register(device, name, RT_DEVICE_FLAG_RDWR); -} diff --git a/IoTGateWay/components/drivers/spi/spi_flash.h b/IoTGateWay/components/drivers/spi/spi_flash.h deleted file mode 100644 index 30db32474a984..0000000000000 --- a/IoTGateWay/components/drivers/spi/spi_flash.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2016/5/20 bernard the first version - */ - -#ifndef SPI_FLASH_H__ -#define SPI_FLASH_H__ - -struct spi_flash_device -{ - struct rt_device flash_device; - struct rt_device_blk_geometry geometry; - struct rt_spi_device * rt_spi_device; - struct rt_mutex lock; - void * user_data; -}; - -typedef struct spi_flash_device *rt_spi_flash_device_t; - -#ifdef RT_USING_MTD_NOR -struct spi_flash_mtd -{ - struct rt_mtd_nor_device mtd_device; - struct rt_spi_device * rt_spi_device; - struct rt_mutex lock; - void * user_data; -}; -#endif - -#endif diff --git a/IoTGateWay/components/drivers/spi/spi_flash_sfud.c b/IoTGateWay/components/drivers/spi/spi_flash_sfud.c deleted file mode 100644 index eff604fe02799..0000000000000 --- a/IoTGateWay/components/drivers/spi/spi_flash_sfud.c +++ /dev/null @@ -1,798 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2016-09-28 armink first version. - */ - -#include -#include -#include "spi_flash.h" -#include "spi_flash_sfud.h" - -#ifdef RT_USING_SFUD - -#ifdef RT_DEBUG_SFUD -#define DEBUG_TRACE rt_kprintf("[SFUD] "); rt_kprintf -#else -#define DEBUG_TRACE(...) -#endif /* RT_DEBUG_SFUD */ - -#ifndef RT_SFUD_DEFAULT_SPI_CFG - -#ifndef RT_SFUD_SPI_MAX_HZ -#define RT_SFUD_SPI_MAX_HZ 50000000 -#endif - -/* read the JEDEC SFDP command must run at 50 MHz or less */ -#define RT_SFUD_DEFAULT_SPI_CFG \ -{ \ - .mode = RT_SPI_MODE_0 | RT_SPI_MSB, \ - .data_width = 8, \ - .max_hz = RT_SFUD_SPI_MAX_HZ, \ -} -#endif - -#ifdef SFUD_USING_QSPI -#define RT_SFUD_DEFAULT_QSPI_CFG \ -{ \ - RT_SFUD_DEFAULT_SPI_CFG, \ - .medium_size = 0x800000, \ - .ddr_mode = 0, \ - .qspi_dl_width = 4, \ -} -#endif - -static char log_buf[RT_CONSOLEBUF_SIZE]; - -void sfud_log_debug(const char *file, const long line, const char *format, ...); - -static rt_err_t rt_sfud_control(rt_device_t dev, int cmd, void *args) { - RT_ASSERT(dev); - - switch (cmd) { - case RT_DEVICE_CTRL_BLK_GETGEOME: { - struct rt_device_blk_geometry *geometry = (struct rt_device_blk_geometry *) args; - struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (dev->user_data); - - if (rtt_dev == RT_NULL || geometry == RT_NULL) { - return -RT_ERROR; - } - - geometry->bytes_per_sector = rtt_dev->geometry.bytes_per_sector; - geometry->sector_count = rtt_dev->geometry.sector_count; - geometry->block_size = rtt_dev->geometry.block_size; - break; - } - case RT_DEVICE_CTRL_BLK_ERASE: { - rt_uint32_t *addrs = (rt_uint32_t *) args, start_addr = addrs[0], end_addr = addrs[1], phy_start_addr; - struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (dev->user_data); - sfud_flash *sfud_dev = (sfud_flash *) (rtt_dev->user_data); - rt_size_t phy_size; - - if (addrs == RT_NULL || start_addr > end_addr || rtt_dev == RT_NULL || sfud_dev == RT_NULL) { - return -RT_ERROR; - } - - if (end_addr == start_addr) { - end_addr ++; - } - - phy_start_addr = start_addr * rtt_dev->geometry.bytes_per_sector; - phy_size = (end_addr - start_addr) * rtt_dev->geometry.bytes_per_sector; - - if (sfud_erase(sfud_dev, phy_start_addr, phy_size) != SFUD_SUCCESS) { - return -RT_ERROR; - } - break; - } - } - - return RT_EOK; -} - - -static rt_size_t rt_sfud_read(rt_device_t dev, rt_off_t pos, void* buffer, rt_size_t size) { - struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (dev->user_data); - sfud_flash *sfud_dev = (sfud_flash *) (rtt_dev->user_data); - - RT_ASSERT(dev); - RT_ASSERT(rtt_dev); - RT_ASSERT(sfud_dev); - /* change the block device's logic address to physical address */ - rt_off_t phy_pos = pos * rtt_dev->geometry.bytes_per_sector; - rt_size_t phy_size = size * rtt_dev->geometry.bytes_per_sector; - - if (sfud_read(sfud_dev, phy_pos, phy_size, buffer) != SFUD_SUCCESS) { - return 0; - } else { - return size; - } -} - -static rt_size_t rt_sfud_write(rt_device_t dev, rt_off_t pos, const void* buffer, rt_size_t size) { - struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (dev->user_data); - sfud_flash *sfud_dev = (sfud_flash *) (rtt_dev->user_data); - - RT_ASSERT(dev); - RT_ASSERT(rtt_dev); - RT_ASSERT(sfud_dev); - /* change the block device's logic address to physical address */ - rt_off_t phy_pos = pos * rtt_dev->geometry.bytes_per_sector; - rt_size_t phy_size = size * rtt_dev->geometry.bytes_per_sector; - - if (sfud_erase_write(sfud_dev, phy_pos, phy_size, buffer) != SFUD_SUCCESS) { - return 0; - } else { - return size; - } -} - -/** - * SPI write data then read data - */ -static sfud_err spi_write_read(const sfud_spi *spi, const uint8_t *write_buf, size_t write_size, uint8_t *read_buf, - size_t read_size) { - sfud_err result = SFUD_SUCCESS; - sfud_flash *sfud_dev = (sfud_flash *) (spi->user_data); - struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (sfud_dev->user_data); - - RT_ASSERT(spi); - RT_ASSERT(sfud_dev); - RT_ASSERT(rtt_dev); -#ifdef SFUD_USING_QSPI - struct rt_qspi_device *qspi_dev = RT_NULL; -#endif - if (write_size) { - RT_ASSERT(write_buf); - } - if (read_size) { - RT_ASSERT(read_buf); - } -#ifdef SFUD_USING_QSPI - if(rtt_dev->rt_spi_device->bus->mode & RT_SPI_BUS_MODE_QSPI) { - qspi_dev = (struct rt_qspi_device *) (rtt_dev->rt_spi_device); - if (write_size && read_size) { - if (rt_qspi_send_then_recv(qspi_dev, write_buf, write_size, read_buf, read_size) <= 0) { - result = SFUD_ERR_TIMEOUT; - } - } else if (write_size) { - if (rt_qspi_send(qspi_dev, write_buf, write_size) <= 0) { - result = SFUD_ERR_TIMEOUT; - } - } - } - else -#endif - { - if (write_size && read_size) { - if (rt_spi_send_then_recv(rtt_dev->rt_spi_device, write_buf, write_size, read_buf, read_size) != RT_EOK) { - result = SFUD_ERR_TIMEOUT; - } - } else if (write_size) { - if (rt_spi_send(rtt_dev->rt_spi_device, write_buf, write_size) <= 0) { - result = SFUD_ERR_TIMEOUT; - } - } else { - if (rt_spi_recv(rtt_dev->rt_spi_device, read_buf, read_size) <= 0) { - result = SFUD_ERR_TIMEOUT; - } - } - } - - return result; -} - -#ifdef SFUD_USING_QSPI -/** - * QSPI fast read data - */ -static sfud_err qspi_read(const struct __sfud_spi *spi, uint32_t addr, sfud_qspi_read_cmd_format *qspi_read_cmd_format, uint8_t *read_buf, size_t read_size) { - struct rt_qspi_message message; - sfud_err result = SFUD_SUCCESS; - - sfud_flash *sfud_dev = (sfud_flash *) (spi->user_data); - struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (sfud_dev->user_data); - struct rt_qspi_device *qspi_dev = (struct rt_qspi_device *) (rtt_dev->rt_spi_device); - - RT_ASSERT(spi); - RT_ASSERT(sfud_dev); - RT_ASSERT(rtt_dev); - RT_ASSERT(qspi_dev); - - /* set message struct */ - message.instruction.content = qspi_read_cmd_format->instruction; - message.instruction.qspi_lines = qspi_read_cmd_format->instruction_lines; - - message.address.content = addr; - message.address.size = qspi_read_cmd_format->address_size; - message.address.qspi_lines = qspi_read_cmd_format->address_lines; - - message.alternate_bytes.content = 0; - message.alternate_bytes.size = 0; - message.alternate_bytes.qspi_lines = 0; - - message.dummy_cycles = qspi_read_cmd_format->dummy_cycles; - - message.parent.send_buf = RT_NULL; - message.parent.recv_buf = read_buf; - message.parent.length = read_size; - message.parent.cs_release = 1; - message.parent.cs_take = 1; - message.qspi_data_lines = qspi_read_cmd_format->data_lines; - - if (rt_qspi_transfer_message(qspi_dev, &message) != read_size) { - result = SFUD_ERR_TIMEOUT; - } - - return result; -} -#endif - -static void spi_lock(const sfud_spi *spi) { - sfud_flash *sfud_dev = (sfud_flash *) (spi->user_data); - struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (sfud_dev->user_data); - - RT_ASSERT(spi); - RT_ASSERT(sfud_dev); - RT_ASSERT(rtt_dev); - - rt_mutex_take(&(rtt_dev->lock), RT_WAITING_FOREVER); -} - -static void spi_unlock(const sfud_spi *spi) { - sfud_flash *sfud_dev = (sfud_flash *) (spi->user_data); - struct spi_flash_device *rtt_dev = (struct spi_flash_device *) (sfud_dev->user_data); - - RT_ASSERT(spi); - RT_ASSERT(sfud_dev); - RT_ASSERT(rtt_dev); - - rt_mutex_release(&(rtt_dev->lock)); -} - -static void retry_delay_100us(void) { - /* 100 microsecond delay */ - rt_thread_delay((RT_TICK_PER_SECOND * 1 + 9999) / 10000); -} - -/** - * This function is print debug info. - * - * @param file the file which has call this function - * @param line the line number which has call this function - * @param format output format - * @param ... args - */ -void sfud_log_debug(const char *file, const long line, const char *format, ...) { - va_list args; - - /* args point to the first variable parameter */ - va_start(args, format); - rt_kprintf("[SFUD] (%s:%ld) ", file, line); - /* must use vprintf to print */ - rt_vsnprintf(log_buf, sizeof(log_buf), format, args); - rt_kprintf("%s\n", log_buf); - va_end(args); -} - -/** - * This function is print routine info. - * - * @param format output format - * @param ... args - */ -void sfud_log_info(const char *format, ...) { - va_list args; - - /* args point to the first variable parameter */ - va_start(args, format); - rt_kprintf("[SFUD] "); - /* must use vprintf to print */ - rt_vsnprintf(log_buf, sizeof(log_buf), format, args); - rt_kprintf("%s\n", log_buf); - va_end(args); -} - -sfud_err sfud_spi_port_init(sfud_flash *flash) { - sfud_err result = SFUD_SUCCESS; - - RT_ASSERT(flash); - - /* port SPI device interface */ - flash->spi.wr = spi_write_read; -#ifdef SFUD_USING_QSPI - flash->spi.qspi_read = qspi_read; -#endif - flash->spi.lock = spi_lock; - flash->spi.unlock = spi_unlock; - flash->spi.user_data = flash; - if (RT_TICK_PER_SECOND < 1000) { - rt_kprintf("[SFUD] Warning: The OS tick(%d) is less than 1000. So the flash write will take more time.\n", RT_TICK_PER_SECOND); - } - /* 100 microsecond delay */ - flash->retry.delay = retry_delay_100us; - /* 60 seconds timeout */ - flash->retry.times = 60 * 10000; - - return result; -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops flash_device_ops = -{ - RT_NULL, - RT_NULL, - RT_NULL, - rt_sfud_read, - rt_sfud_write, - rt_sfud_control -}; -#endif - -/** - * Probe SPI flash by SFUD(Serial Flash Universal Driver) driver library and though SPI device. - * - * @param spi_flash_dev_name the name which will create SPI flash device - * @param spi_dev_name using SPI device name - * - * @return probed SPI flash device, probe failed will return RT_NULL - */ -rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const char *spi_dev_name) { - rt_spi_flash_device_t rtt_dev = RT_NULL; - sfud_flash *sfud_dev = RT_NULL; - char *spi_flash_dev_name_bak = RT_NULL, *spi_dev_name_bak = RT_NULL; - /* using default flash SPI configuration for initialize SPI Flash - * @note you also can change the SPI to other configuration after initialized finish */ - struct rt_spi_configuration cfg = RT_SFUD_DEFAULT_SPI_CFG; - extern sfud_err sfud_device_init(sfud_flash *flash); -#ifdef SFUD_USING_QSPI - struct rt_qspi_configuration qspi_cfg = RT_SFUD_DEFAULT_QSPI_CFG; - struct rt_qspi_device *qspi_dev = RT_NULL; -#endif - - RT_ASSERT(spi_flash_dev_name); - RT_ASSERT(spi_dev_name); - - rtt_dev = (rt_spi_flash_device_t) rt_malloc(sizeof(struct spi_flash_device)); - sfud_dev = (sfud_flash_t) rt_malloc(sizeof(sfud_flash)); - spi_flash_dev_name_bak = (char *) rt_malloc(rt_strlen(spi_flash_dev_name) + 1); - spi_dev_name_bak = (char *) rt_malloc(rt_strlen(spi_dev_name) + 1); - - if (rtt_dev) { - rt_memset(rtt_dev, 0, sizeof(struct spi_flash_device)); - /* initialize lock */ - rt_mutex_init(&(rtt_dev->lock), spi_flash_dev_name, RT_IPC_FLAG_FIFO); - } - - if (rtt_dev && sfud_dev && spi_flash_dev_name_bak && spi_dev_name_bak) { - rt_memset(sfud_dev, 0, sizeof(sfud_flash)); - rt_strncpy(spi_flash_dev_name_bak, spi_flash_dev_name, rt_strlen(spi_flash_dev_name)); - rt_strncpy(spi_dev_name_bak, spi_dev_name, rt_strlen(spi_dev_name)); - /* make string end sign */ - spi_flash_dev_name_bak[rt_strlen(spi_flash_dev_name)] = '\0'; - spi_dev_name_bak[rt_strlen(spi_dev_name)] = '\0'; - /* SPI configure */ - { - /* RT-Thread SPI device initialize */ - rtt_dev->rt_spi_device = (struct rt_spi_device *) rt_device_find(spi_dev_name); - if (rtt_dev->rt_spi_device == RT_NULL || rtt_dev->rt_spi_device->parent.type != RT_Device_Class_SPIDevice) { - rt_kprintf("ERROR: SPI device %s not found!\n", spi_dev_name); - goto error; - } - sfud_dev->spi.name = spi_dev_name_bak; - -#ifdef SFUD_USING_QSPI - /* set the qspi line number and configure the QSPI bus */ - if(rtt_dev->rt_spi_device->bus->mode &RT_SPI_BUS_MODE_QSPI) { - qspi_dev = (struct rt_qspi_device *)rtt_dev->rt_spi_device; - qspi_cfg.qspi_dl_width = qspi_dev->config.qspi_dl_width; - rt_qspi_configure(qspi_dev, &qspi_cfg); - } - else -#endif - rt_spi_configure(rtt_dev->rt_spi_device, &cfg); - } - /* SFUD flash device initialize */ - { - sfud_dev->name = spi_flash_dev_name_bak; - /* accessed each other */ - rtt_dev->user_data = sfud_dev; - rtt_dev->rt_spi_device->user_data = rtt_dev; - rtt_dev->flash_device.user_data = rtt_dev; - sfud_dev->user_data = rtt_dev; - /* initialize SFUD device */ - if (sfud_device_init(sfud_dev) != SFUD_SUCCESS) { - rt_kprintf("ERROR: SPI flash probe failed by SPI device %s.\n", spi_dev_name); - goto error; - } - /* when initialize success, then copy SFUD flash device's geometry to RT-Thread SPI flash device */ - rtt_dev->geometry.sector_count = sfud_dev->chip.capacity / sfud_dev->chip.erase_gran; - rtt_dev->geometry.bytes_per_sector = sfud_dev->chip.erase_gran; - rtt_dev->geometry.block_size = sfud_dev->chip.erase_gran; -#ifdef SFUD_USING_QSPI - /* reconfigure the QSPI bus for medium size */ - if(rtt_dev->rt_spi_device->bus->mode &RT_SPI_BUS_MODE_QSPI) { - qspi_cfg.medium_size = sfud_dev->chip.capacity; - rt_qspi_configure(qspi_dev, &qspi_cfg); - if(qspi_dev->enter_qspi_mode != RT_NULL) - qspi_dev->enter_qspi_mode(qspi_dev); - - /* set data lines width */ - sfud_qspi_fast_read_enable(sfud_dev, qspi_dev->config.qspi_dl_width); - } -#endif /* SFUD_USING_QSPI */ - } - - /* register device */ - rtt_dev->flash_device.type = RT_Device_Class_Block; -#ifdef RT_USING_DEVICE_OPS - rtt_dev->flash_device.ops = &flash_device_ops; -#else - rtt_dev->flash_device.init = RT_NULL; - rtt_dev->flash_device.open = RT_NULL; - rtt_dev->flash_device.close = RT_NULL; - rtt_dev->flash_device.read = rt_sfud_read; - rtt_dev->flash_device.write = rt_sfud_write; - rtt_dev->flash_device.control = rt_sfud_control; -#endif - - rt_device_register(&(rtt_dev->flash_device), spi_flash_dev_name, RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_STANDALONE); - - DEBUG_TRACE("Probe SPI flash %s by SPI device %s success.\n",spi_flash_dev_name, spi_dev_name); - return rtt_dev; - } else { - rt_kprintf("ERROR: Low memory.\n"); - goto error; - } - -error: - - if (rtt_dev) { - rt_mutex_detach(&(rtt_dev->lock)); - } - /* may be one of objects memory was malloc success, so need free all */ - rt_free(rtt_dev); - rt_free(sfud_dev); - rt_free(spi_flash_dev_name_bak); - rt_free(spi_dev_name_bak); - - return RT_NULL; -} - -/** - * Delete SPI flash device - * - * @param spi_flash_dev SPI flash device - * - * @return the operation status, RT_EOK on successful - */ -rt_err_t rt_sfud_flash_delete(rt_spi_flash_device_t spi_flash_dev) { - sfud_flash *sfud_flash_dev = (sfud_flash *) (spi_flash_dev->user_data); - - RT_ASSERT(spi_flash_dev); - RT_ASSERT(sfud_flash_dev); - - rt_device_unregister(&(spi_flash_dev->flash_device)); - - rt_mutex_detach(&(spi_flash_dev->lock)); - - rt_free(sfud_flash_dev->spi.name); - rt_free(sfud_flash_dev->name); - rt_free(sfud_flash_dev); - rt_free(spi_flash_dev); - - return RT_EOK; -} - -sfud_flash_t rt_sfud_flash_find(const char *spi_dev_name) -{ - rt_spi_flash_device_t rtt_dev = RT_NULL; - struct rt_spi_device *rt_spi_device = RT_NULL; - sfud_flash_t sfud_dev = RT_NULL; - - rt_spi_device = (struct rt_spi_device *) rt_device_find(spi_dev_name); - if (rt_spi_device == RT_NULL || rt_spi_device->parent.type != RT_Device_Class_SPIDevice) { - rt_kprintf("ERROR: SPI device %s not found!\n", spi_dev_name); - goto __error; - } - - rtt_dev = (rt_spi_flash_device_t) (rt_spi_device->user_data); - if (rtt_dev && rtt_dev->user_data) { - sfud_dev = (sfud_flash_t) (rtt_dev->user_data); - return sfud_dev; - } else { - rt_kprintf("ERROR: SFUD flash device not found!\n"); - goto __error; - } - -__error: - return RT_NULL; -} - -sfud_flash_t rt_sfud_flash_find_by_dev_name(const char *flash_dev_name) -{ - rt_spi_flash_device_t rtt_dev = RT_NULL; - sfud_flash_t sfud_dev = RT_NULL; - - rtt_dev = (rt_spi_flash_device_t) rt_device_find(flash_dev_name); - if (rtt_dev == RT_NULL || rtt_dev->flash_device.type != RT_Device_Class_Block) { - rt_kprintf("ERROR: Flash device %s not found!\n", flash_dev_name); - goto __error; - } - - if (rtt_dev->user_data) { - sfud_dev = (sfud_flash_t) (rtt_dev->user_data); - return sfud_dev; - } else { - rt_kprintf("ERROR: SFUD flash device not found!\n"); - goto __error; - } - -__error: - return RT_NULL; -} - -#if defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) - -#include - -static void sf(uint8_t argc, char **argv) { - -#define __is_print(ch) ((unsigned int)((ch) - ' ') < 127u - ' ') -#define HEXDUMP_WIDTH 16 -#define CMD_PROBE_INDEX 0 -#define CMD_READ_INDEX 1 -#define CMD_WRITE_INDEX 2 -#define CMD_ERASE_INDEX 3 -#define CMD_RW_STATUS_INDEX 4 -#define CMD_BENCH_INDEX 5 - - sfud_err result = SFUD_SUCCESS; - static const sfud_flash *sfud_dev = NULL; - static rt_spi_flash_device_t rtt_dev = NULL, rtt_dev_bak = NULL; - size_t i = 0, j = 0; - - const char* sf_help_info[] = { - [CMD_PROBE_INDEX] = "sf probe [spi_device] - probe and init SPI flash by given 'spi_device'", - [CMD_READ_INDEX] = "sf read addr size - read 'size' bytes starting at 'addr'", - [CMD_WRITE_INDEX] = "sf write addr data1 ... dataN - write some bytes 'data' to flash starting at 'addr'", - [CMD_ERASE_INDEX] = "sf erase addr size - erase 'size' bytes starting at 'addr'", - [CMD_RW_STATUS_INDEX] = "sf status [ ] - read or write '1:volatile|0:non-volatile' 'status'", - [CMD_BENCH_INDEX] = "sf bench - full chip benchmark. DANGER: It will erase full chip!", - }; - - if (argc < 2) { - rt_kprintf("Usage:\n"); - for (i = 0; i < sizeof(sf_help_info) / sizeof(char*); i++) { - rt_kprintf("%s\n", sf_help_info[i]); - } - rt_kprintf("\n"); - } else { - const char *operator = argv[1]; - uint32_t addr, size; - - if (!strcmp(operator, "probe")) { - if (argc < 3) { - rt_kprintf("Usage: %s.\n", sf_help_info[CMD_PROBE_INDEX]); - } else { - char *spi_dev_name = argv[2]; - rtt_dev_bak = rtt_dev; - - /* delete the old SPI flash device */ - if(rtt_dev_bak) { - rt_sfud_flash_delete(rtt_dev_bak); - } - - rtt_dev = rt_sfud_flash_probe("sf_cmd", spi_dev_name); - if (!rtt_dev) { - return; - } - - sfud_dev = (sfud_flash_t)rtt_dev->user_data; - if (sfud_dev->chip.capacity < 1024 * 1024) { - rt_kprintf("%d KB %s is current selected device.\n", sfud_dev->chip.capacity / 1024, sfud_dev->name); - } else { - rt_kprintf("%d MB %s is current selected device.\n", sfud_dev->chip.capacity / 1024 / 1024, - sfud_dev->name); - } - } - } else { - if (!sfud_dev) { - rt_kprintf("No flash device selected. Please run 'sf probe'.\n"); - return; - } - if (!rt_strcmp(operator, "read")) { - if (argc < 4) { - rt_kprintf("Usage: %s.\n", sf_help_info[CMD_READ_INDEX]); - return; - } else { - addr = strtol(argv[2], NULL, 0); - size = strtol(argv[3], NULL, 0); - uint8_t *data = rt_malloc(size); - if (data) { - result = sfud_read(sfud_dev, addr, size, data); - if (result == SFUD_SUCCESS) { - rt_kprintf("Read the %s flash data success. Start from 0x%08X, size is %ld. The data is:\n", - sfud_dev->name, addr, size); - rt_kprintf("Offset (h) 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F\n"); - for (i = 0; i < size; i += HEXDUMP_WIDTH) - { - rt_kprintf("[%08X] ", addr + i); - /* dump hex */ - for (j = 0; j < HEXDUMP_WIDTH; j++) { - if (i + j < size) { - rt_kprintf("%02X ", data[i + j]); - } else { - rt_kprintf(" "); - } - } - /* dump char for hex */ - for (j = 0; j < HEXDUMP_WIDTH; j++) { - if (i + j < size) { - rt_kprintf("%c", __is_print(data[i + j]) ? data[i + j] : '.'); - } - } - rt_kprintf("\n"); - } - rt_kprintf("\n"); - } - rt_free(data); - } else { - rt_kprintf("Low memory!\n"); - } - } - } else if (!rt_strcmp(operator, "write")) { - if (argc < 4) { - rt_kprintf("Usage: %s.\n", sf_help_info[CMD_WRITE_INDEX]); - return; - } else { - addr = strtol(argv[2], NULL, 0); - size = argc - 3; - uint8_t *data = rt_malloc(size); - if (data) { - for (i = 0; i < size; i++) { - data[i] = strtol(argv[3 + i], NULL, 0); - } - result = sfud_write(sfud_dev, addr, size, data); - if (result == SFUD_SUCCESS) { - rt_kprintf("Write the %s flash data success. Start from 0x%08X, size is %ld.\n", - sfud_dev->name, addr, size); - rt_kprintf("Write data: "); - for (i = 0; i < size; i++) { - rt_kprintf("%d ", data[i]); - } - rt_kprintf(".\n"); - } - rt_free(data); - } else { - rt_kprintf("Low memory!\n"); - } - } - } else if (!rt_strcmp(operator, "erase")) { - if (argc < 4) { - rt_kprintf("Usage: %s.\n", sf_help_info[CMD_ERASE_INDEX]); - return; - } else { - addr = strtol(argv[2], NULL, 0); - size = strtol(argv[3], NULL, 0); - result = sfud_erase(sfud_dev, addr, size); - if (result == SFUD_SUCCESS) { - rt_kprintf("Erase the %s flash data success. Start from 0x%08X, size is %ld.\n", sfud_dev->name, - addr, size); - } - } - } else if (!rt_strcmp(operator, "status")) { - if (argc < 3) { - uint8_t status; - result = sfud_read_status(sfud_dev, &status); - if (result == SFUD_SUCCESS) { - rt_kprintf("The %s flash status register current value is 0x%02X.\n", sfud_dev->name, status); - } - } else if (argc == 4) { - bool is_volatile = strtol(argv[2], NULL, 0); - uint8_t status = strtol(argv[3], NULL, 0); - result = sfud_write_status(sfud_dev, is_volatile, status); - if (result == SFUD_SUCCESS) { - rt_kprintf("Write the %s flash status register to 0x%02X success.\n", sfud_dev->name, status); - } - } else { - rt_kprintf("Usage: %s.\n", sf_help_info[CMD_RW_STATUS_INDEX]); - return; - } - } else if (!rt_strcmp(operator, "bench")) { - if ((argc > 2 && rt_strcmp(argv[2], "yes")) || argc < 3) { - rt_kprintf("DANGER: It will erase full chip! Please run 'sf bench yes'.\n"); - return; - } - /* full chip benchmark test */ - addr = 0; - size = sfud_dev->chip.capacity; - uint32_t start_time, time_cast; - size_t write_size = SFUD_WRITE_MAX_PAGE_SIZE, read_size = SFUD_WRITE_MAX_PAGE_SIZE; - uint8_t *write_data = rt_malloc(write_size), *read_data = rt_malloc(read_size); - - if (write_data && read_data) { - rt_memset(write_data, 0x55, write_size); - /* benchmark testing */ - rt_kprintf("Erasing the %s %ld bytes data, waiting...\n", sfud_dev->name, size); - start_time = rt_tick_get(); - result = sfud_erase(sfud_dev, addr, size); - if (result == SFUD_SUCCESS) { - time_cast = rt_tick_get() - start_time; - rt_kprintf("Erase benchmark success, total time: %d.%03dS.\n", time_cast / RT_TICK_PER_SECOND, - time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000)); - } else { - rt_kprintf("Erase benchmark has an error. Error code: %d.\n", result); - } - /* write test */ - rt_kprintf("Writing the %s %ld bytes data, waiting...\n", sfud_dev->name, size); - start_time = rt_tick_get(); - for (i = 0; i < size; i += write_size) { - result = sfud_write(sfud_dev, addr + i, write_size, write_data); - if (result != SFUD_SUCCESS) { - rt_kprintf("Writing %s failed, already wr for %lu bytes, write %d each time\n", sfud_dev->name, i, write_size); - break; - } - } - if (result == SFUD_SUCCESS) { - time_cast = rt_tick_get() - start_time; - rt_kprintf("Write benchmark success, total time: %d.%03dS.\n", time_cast / RT_TICK_PER_SECOND, - time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000)); - } else { - rt_kprintf("Write benchmark has an error. Error code: %d.\n", result); - } - /* read test */ - rt_kprintf("Reading the %s %ld bytes data, waiting...\n", sfud_dev->name, size); - start_time = rt_tick_get(); - for (i = 0; i < size; i += read_size) { - if (i + read_size <= size) { - result = sfud_read(sfud_dev, addr + i, read_size, read_data); - } else { - result = sfud_read(sfud_dev, addr + i, size - i, read_data); - } - /* data check */ - if (memcmp(write_data, read_data, read_size)) - { - rt_kprintf("Data check ERROR! Please check you flash by other command.\n"); - result = SFUD_ERR_READ; - } - - if (result != SFUD_SUCCESS) { - rt_kprintf("Read %s failed, already rd for %lu bytes, read %d each time\n", sfud_dev->name, i, read_size); - break; - } - } - if (result == SFUD_SUCCESS) { - time_cast = rt_tick_get() - start_time; - rt_kprintf("Read benchmark success, total time: %d.%03dS.\n", time_cast / RT_TICK_PER_SECOND, - time_cast % RT_TICK_PER_SECOND / ((RT_TICK_PER_SECOND * 1 + 999) / 1000)); - } else { - rt_kprintf("Read benchmark has an error. Error code: %d.\n", result); - } - } else { - rt_kprintf("Low memory!\n"); - } - rt_free(write_data); - rt_free(read_data); - } else { - rt_kprintf("Usage:\n"); - for (i = 0; i < sizeof(sf_help_info) / sizeof(char*); i++) { - rt_kprintf("%s\n", sf_help_info[i]); - } - rt_kprintf("\n"); - return; - } - if (result != SFUD_SUCCESS) { - rt_kprintf("This flash operate has an error. Error code: %d.\n", result); - } - } - } -} -MSH_CMD_EXPORT(sf, SPI Flash operate.); -#endif /* defined(RT_USING_FINSH) && defined(FINSH_USING_MSH) */ - -#endif /* RT_USING_SFUD */ diff --git a/IoTGateWay/components/drivers/spi/spi_flash_sfud.h b/IoTGateWay/components/drivers/spi/spi_flash_sfud.h deleted file mode 100644 index 490f2feadb761..0000000000000 --- a/IoTGateWay/components/drivers/spi/spi_flash_sfud.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2016-09-28 armink first version. - */ - -#ifndef _SPI_FLASH_SFUD_H_ -#define _SPI_FLASH_SFUD_H_ - -#include -#include -#include "./sfud/inc/sfud.h" -#include "spi_flash.h" - -/** - * Probe SPI flash by SFUD(Serial Flash Universal Driver) driver library and though SPI device. - * - * @param spi_flash_dev_name the name which will create SPI flash device - * @param spi_dev_name using SPI device name - * - * @return probed SPI flash device, probe failed will return RT_NULL - */ -rt_spi_flash_device_t rt_sfud_flash_probe(const char *spi_flash_dev_name, const char *spi_dev_name); - -/** - * Delete SPI flash device - * - * @param spi_flash_dev SPI flash device - * - * @return the operation status, RT_EOK on successful - */ -rt_err_t rt_sfud_flash_delete(rt_spi_flash_device_t spi_flash_dev); - -/** - * Find sfud flash device by SPI device name - * - * @param spi_dev_name using SPI device name - * - * @return sfud flash device if success, otherwise return RT_NULL - */ -sfud_flash_t rt_sfud_flash_find(const char *spi_dev_name); - -/** - * Find sfud flash device by flash device name - * - * @param flash_dev_name using flash device name - * - * @return sfud flash device if success, otherwise return RT_NULL - */ -sfud_flash_t rt_sfud_flash_find_by_dev_name(const char *flash_dev_name); - -#endif /* _SPI_FLASH_SFUD_H_ */ diff --git a/IoTGateWay/components/drivers/spi/spi_msd.c b/IoTGateWay/components/drivers/spi/spi_msd.c deleted file mode 100644 index a109fd94888e5..0000000000000 --- a/IoTGateWay/components/drivers/spi/spi_msd.c +++ /dev/null @@ -1,1654 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2009-04-17 Bernard first version. - * 2010-07-15 aozima Modify read/write according new block driver interface. - * 2012-02-01 aozima use new RT-Thread SPI drivers. - * 2012-04-11 aozima get max. data transfer rate from CSD[TRAN_SPEED]. - * 2012-05-21 aozima update MMC card support. - * 2018-03-09 aozima fixed CSD Version 2.0 sector count calc. - */ - -#include -#include "spi_msd.h" - -//#define MSD_TRACE - -#ifdef MSD_TRACE - #define MSD_DEBUG(...) rt_kprintf("[MSD] %d ", rt_tick_get()); rt_kprintf(__VA_ARGS__); -#else - #define MSD_DEBUG(...) -#endif /* #ifdef MSD_TRACE */ - -#define DUMMY 0xFF - -#define CARD_NCR_MAX 9 - -#define CARD_NRC 1 -#define CARD_NCR 1 - -static struct msd_device _msd_device; - -/* function define */ -static rt_bool_t rt_tick_timeout(rt_tick_t tick_start, rt_tick_t tick_long); - -static rt_err_t MSD_take_owner(struct rt_spi_device *spi_device); - -static rt_err_t _wait_token(struct rt_spi_device *device, uint8_t token); -static rt_err_t _wait_ready(struct rt_spi_device *device); -static rt_err_t rt_msd_init(rt_device_t dev); -static rt_err_t rt_msd_open(rt_device_t dev, rt_uint16_t oflag); -static rt_err_t rt_msd_close(rt_device_t dev); -static rt_size_t rt_msd_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size); -static rt_size_t rt_msd_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size); -static rt_size_t rt_msd_sdhc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size); -static rt_size_t rt_msd_sdhc_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size); -static rt_err_t rt_msd_control(rt_device_t dev, int cmd, void *args); - -static rt_err_t MSD_take_owner(struct rt_spi_device *spi_device) -{ - rt_err_t result; - - result = rt_mutex_take(&(spi_device->bus->lock), RT_WAITING_FOREVER); - if (result == RT_EOK) - { - if (spi_device->bus->owner != spi_device) - { - /* not the same owner as current, re-configure SPI bus */ - result = spi_device->bus->ops->configure(spi_device, &spi_device->config); - if (result == RT_EOK) - { - /* set SPI bus owner */ - spi_device->bus->owner = spi_device; - } - } - } - - return result; -} - -static rt_bool_t rt_tick_timeout(rt_tick_t tick_start, rt_tick_t tick_long) -{ - rt_tick_t tick_end = tick_start + tick_long; - rt_tick_t tick_now = rt_tick_get(); - rt_bool_t result = RT_FALSE; - - if (tick_end >= tick_start) - { - if (tick_now >= tick_end) - { - result = RT_TRUE; - } - else - { - result = RT_FALSE; - } - } - else - { - if ((tick_now < tick_start) && (tick_now >= tick_end)) - { - result = RT_TRUE; - } - else - { - result = RT_FALSE; - } - } - - return result; -} - -static uint8_t crc7(const uint8_t *buf, int len) -{ - unsigned char i, j, crc, ch, ch2, ch3; - - crc = 0; - - for (i = 0; i < len; i ++) - { - ch = buf[i]; - - for (j = 0; j < 8; j ++, ch <<= 1) - { - ch2 = (crc & 0x40) ? 1 : 0; - ch3 = (ch & 0x80) ? 1 : 0; - - if (ch2 ^ ch3) - { - crc ^= 0x04; - crc <<= 1; - crc |= 0x01; - } - else - { - crc <<= 1; - } - } - } - - return crc; -} - -static rt_err_t _send_cmd( - struct rt_spi_device *device, - uint8_t cmd, - uint32_t arg, - uint8_t crc, - response_type type, - uint8_t *response -) -{ - struct rt_spi_message message; - uint8_t cmd_buffer[8]; - uint8_t recv_buffer[sizeof(cmd_buffer)]; - uint32_t i; - - cmd_buffer[0] = DUMMY; - cmd_buffer[1] = (cmd | 0x40); - cmd_buffer[2] = (uint8_t)(arg >> 24); - cmd_buffer[3] = (uint8_t)(arg >> 16); - cmd_buffer[4] = (uint8_t)(arg >> 8); - cmd_buffer[5] = (uint8_t)(arg); - - if (crc == 0x00) - { - crc = crc7(&cmd_buffer[1], 5); - crc = (crc << 1) | 0x01; - } - cmd_buffer[6] = (crc); - - cmd_buffer[7] = DUMMY; - - /* initial message */ - message.send_buf = cmd_buffer; - message.recv_buf = recv_buffer; - message.length = sizeof(cmd_buffer); - message.cs_take = message.cs_release = 0; - - _wait_ready(device); - - /* transfer message */ - device->bus->ops->xfer(device, &message); - - for (i = CARD_NCR; i < (CARD_NCR_MAX + 1); i++) - { - uint8_t send = DUMMY; - - /* initial message */ - message.send_buf = &send; - message.recv_buf = response; - message.length = 1; - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - - if (0 == (response[0] & 0x80)) - { - break; - } - } /* wait response */ - - if ((CARD_NCR_MAX + 1) == i) - { - return RT_ERROR;//fail - } - - //recieve other byte - if (type == response_r1) - { - return RT_EOK; - } - else if (type == response_r1b) - { - rt_tick_t tick_start = rt_tick_get(); - uint8_t recv; - - while (1) - { - /* initial message */ - message.send_buf = RT_NULL; - message.recv_buf = &recv; - message.length = 1; - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - - if (recv == DUMMY) - { - return RT_EOK; - } - - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(2000))) - { - return RT_ETIMEOUT; - } - } - } - else if (type == response_r2) - { - /* initial message */ - message.send_buf = RT_NULL; - message.recv_buf = response + 1; - message.length = 1; - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - } - else if ((type == response_r3) || (type == response_r7)) - { - /* initial message */ - message.send_buf = RT_NULL; - message.recv_buf = response + 1; - message.length = 4; - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - } - else - { - return RT_ERROR; // unknow type? - } - - return RT_EOK; -} - -static rt_err_t _wait_token(struct rt_spi_device *device, uint8_t token) -{ - struct rt_spi_message message; - rt_tick_t tick_start; - uint8_t send, recv; - - tick_start = rt_tick_get(); - - /* wati token */ - /* initial message */ - send = DUMMY; - message.send_buf = &send; - message.recv_buf = &recv; - message.length = 1; - message.cs_take = message.cs_release = 0; - - while (1) - { - /* transfer message */ - device->bus->ops->xfer(device, &message); - - if (recv == token) - { - return RT_EOK; - } - - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_WAIT_TOKEN_TIMES))) - { - MSD_DEBUG("[err] wait data start token timeout!\r\n"); - return RT_ETIMEOUT; - } - } /* wati token */ -} - -static rt_err_t _wait_ready(struct rt_spi_device *device) -{ - struct rt_spi_message message; - rt_tick_t tick_start; - uint8_t send, recv; - - tick_start = rt_tick_get(); - - send = DUMMY; - /* initial message */ - message.send_buf = &send; - message.recv_buf = &recv; - message.length = 1; - message.cs_take = message.cs_release = 0; - - while (1) - { - /* transfer message */ - device->bus->ops->xfer(device, &message); - - if (recv == DUMMY) - { - return RT_EOK; - } - - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(1000))) - { - MSD_DEBUG("[err] wait ready timeout!\r\n"); - return RT_ETIMEOUT; - } - } -} - -static rt_err_t _read_block(struct rt_spi_device *device, void *buffer, uint32_t block_size) -{ - struct rt_spi_message message; - rt_err_t result; - - /* wati token */ - result = _wait_token(device, MSD_TOKEN_READ_START); - if (result != RT_EOK) - { - return result; - } - - /* read data */ - { - /* initial message */ - message.send_buf = RT_NULL; - message.recv_buf = buffer; - message.length = block_size; - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - } /* read data */ - - /* get crc */ - { - uint8_t recv_buffer[2]; - - /* initial message */ - message.send_buf = RT_NULL; - message.recv_buf = recv_buffer; - message.length = 2; - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - } /* get crc */ - - return RT_EOK; -} - -static rt_err_t _write_block(struct rt_spi_device *device, const void *buffer, uint32_t block_size, uint8_t token) -{ - struct rt_spi_message message; - uint8_t send_buffer[16]; - - rt_memset(send_buffer, DUMMY, sizeof(send_buffer)); - send_buffer[sizeof(send_buffer) - 1] = token; - - /* send start block token */ - { - /* initial message */ - message.send_buf = send_buffer; - message.recv_buf = RT_NULL; - message.length = sizeof(send_buffer); - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - } - - /* send data */ - { - /* initial message */ - message.send_buf = buffer; - message.recv_buf = RT_NULL; - message.length = block_size; - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - } - - /* put crc and get data response */ - { - uint8_t recv_buffer[3]; - uint8_t response; - - /* initial message */ - message.send_buf = send_buffer; - message.recv_buf = recv_buffer; - message.length = sizeof(recv_buffer); - message.cs_take = message.cs_release = 0; - - /* transfer message */ - device->bus->ops->xfer(device, &message); - -// response = 0x0E & recv_buffer[2]; - response = MSD_GET_DATA_RESPONSE(recv_buffer[2]); - if (response != MSD_DATA_OK) - { - MSD_DEBUG("[err] write block fail! data response : 0x%02X\r\n", response); - return RT_ERROR; - } - } - - /* wati ready */ - return _wait_ready(device); -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops msd_ops = -{ - rt_msd_init, - rt_msd_open, - rt_msd_close, - rt_msd_read, - rt_msd_write, - rt_msd_control -}; - -const static struct rt_device_ops msd_sdhc_ops = -{ - rt_msd_init, - rt_msd_open, - rt_msd_close, - rt_msd_sdhc_read, - rt_msd_sdhc_write, - rt_msd_control -}; -#endif - -/* RT-Thread Device Driver Interface */ -static rt_err_t rt_msd_init(rt_device_t dev) -{ - struct msd_device *msd = (struct msd_device *)dev; - uint8_t response[MSD_RESPONSE_MAX_LEN]; - rt_err_t result = RT_EOK; - rt_tick_t tick_start; - uint32_t OCR; - - if (msd->spi_device == RT_NULL) - { - MSD_DEBUG("[err] the SPI SD device has no SPI!\r\n"); - return RT_EIO; - } - - /* config spi */ - { - struct rt_spi_configuration cfg; - cfg.data_width = 8; - cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible Modes 0 */ - cfg.max_hz = 1000 * 400; /* 400kbit/s */ - rt_spi_configure(msd->spi_device, &cfg); - } /* config spi */ - - /* init SD card */ - { - struct rt_spi_message message; - - result = MSD_take_owner(msd->spi_device); - - if (result != RT_EOK) - { - goto _exit; - } - - rt_spi_release(msd->spi_device); - - /* The host shall supply power to the card so that the voltage is reached to Vdd_min within 250ms and - start to supply at least 74 SD clocks to the SD card with keeping CMD line to high. - In case of SPI mode, CS shall be held to high during 74 clock cycles. */ - { - uint8_t send_buffer[100]; /* 100byte > 74 clock */ - - /* initial message */ - memset(send_buffer, DUMMY, sizeof(send_buffer)); - message.send_buf = send_buffer; - message.recv_buf = RT_NULL; - message.length = sizeof(send_buffer); - message.cs_take = message.cs_release = 0; - - /* transfer message */ - msd->spi_device->bus->ops->xfer(msd->spi_device, &message); - } /* send 74 clock */ - - /* Send CMD0 (GO_IDLE_STATE) to put MSD in SPI mode */ - { - tick_start = rt_tick_get(); - - while (1) - { - rt_spi_take(msd->spi_device); - result = _send_cmd(msd->spi_device, GO_IDLE_STATE, 0x00, 0x95, response_r1, response); - rt_spi_release(msd->spi_device); - - if ((result == RT_EOK) && (response[0] == MSD_IN_IDLE_STATE)) - { - break; - } - - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_TRY_TIMES))) - { - MSD_DEBUG("[err] SD card goto IDLE mode timeout!\r\n"); - result = RT_ETIMEOUT; - goto _exit; - } - } - - MSD_DEBUG("[info] SD card goto IDLE mode OK!\r\n"); - } /* Send CMD0 (GO_IDLE_STATE) to put MSD in SPI mode */ - - /* CMD8 */ - { - tick_start = rt_tick_get(); - - do - { - rt_spi_take(msd->spi_device); - result = _send_cmd(msd->spi_device, SEND_IF_COND, 0x01AA, 0x87, response_r7, response); - rt_spi_release(msd->spi_device); - - if (result == RT_EOK) - { - MSD_DEBUG("[info] CMD8 response : 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X\r\n", - response[0], response[1], response[2], response[3], response[4]); - - if (response[0] & (1 << 2)) - { - /* illegal command, SD V1.x or MMC card */ - MSD_DEBUG("[info] CMD8 is illegal command.\r\n"); - MSD_DEBUG("[info] maybe Ver1.X SD Memory Card or MMC card!\r\n"); - msd->card_type = MSD_CARD_TYPE_SD_V1_X; - break; - } - else - { - /* SD V2.0 or later or SDHC or SDXC memory card! */ - MSD_DEBUG("[info] Ver2.00 or later or SDHC or SDXC memory card!\r\n"); - msd->card_type = MSD_CARD_TYPE_SD_V2_X; - } - - if ((0xAA == response[4]) && (0x00 == response[3])) - { - /* SD2.0 not support current voltage */ - MSD_DEBUG("[err] VCA = 0, SD2.0 not surpport current operation voltage range\r\n"); - result = RT_ERROR; - goto _exit; - } - } - else - { - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(200))) - { - MSD_DEBUG("[err] CMD8 SEND_IF_COND timeout!\r\n"); - result = RT_ETIMEOUT; - goto _exit; - } - } - } - while (0xAA != response[4]); - } /* CMD8 */ - - /* Ver1.X SD Memory Card or MMC card */ - if (msd->card_type == MSD_CARD_TYPE_SD_V1_X) - { - rt_bool_t is_sd_v1_x = RT_FALSE; - rt_tick_t tick_start; - - /* try SD Ver1.x */ - while (1) - { - rt_spi_take(msd->spi_device); - - result = _send_cmd(msd->spi_device, READ_OCR, 0x00, 0x00, response_r3, response); - if (result != RT_EOK) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[info] It maybe SD1.x or MMC But it is Not response to CMD58!\r\n"); - goto _exit; - } - - if (0 != (response[0] & 0xFE)) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[info] It look CMD58 as illegal command so it is not SD card!\r\n"); - break; - } - rt_spi_release(msd->spi_device); - - OCR = response[1]; - OCR = (OCR << 8) + response[2]; - OCR = (OCR << 8) + response[3]; - OCR = (OCR << 8) + response[4]; - MSD_DEBUG("[info] OCR is 0x%08X\r\n", OCR); - - if (0 == (OCR & (0x1 << 15))) - { - MSD_DEBUG(("[err] SD 1.x But not surpport current voltage\r\n")); - result = RT_ERROR; - goto _exit; - } - - /* --Send ACMD41 to make card ready */ - tick_start = rt_tick_get(); - - /* try CMD55 + ACMD41 */ - while (1) - { - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_TRY_TIMES_ACMD41))) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[info] try CMD55 + ACMD41 timeout! mabey MMC card!\r\n"); - break; - } - - rt_spi_take(msd->spi_device); - - /* CMD55 APP_CMD */ - result = _send_cmd(msd->spi_device, APP_CMD, 0x00, 0x00, response_r1, response); - if (result != RT_EOK) - { - rt_spi_release(msd->spi_device); - continue; - } - - if (0 != (response[0] & 0xFE)) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[info] Not SD card2 , may be MMC\r\n"); - break; - } - - /* ACMD41 SD_SEND_OP_COND */ - result = _send_cmd(msd->spi_device, SD_SEND_OP_COND, 0x00, 0x00, response_r1, response); - if (result != RT_EOK) - { - rt_spi_release(msd->spi_device); - continue; - } - - if (0 != (response[0] & 0xFE)) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[info] Not SD card4 , may be MMC\r\n"); - break; - } - - if (0 == (response[0] & 0xFF)) - { - rt_spi_release(msd->spi_device); - is_sd_v1_x = RT_TRUE; - MSD_DEBUG("[info] It is Ver1.X SD Memory Card!!!\r\n"); - break; - } - } /* try CMD55 + ACMD41 */ - - break; - } /* try SD Ver1.x */ - - /* try MMC */ - if (is_sd_v1_x != RT_TRUE) - { - uint32_t i; - - MSD_DEBUG("[info] try MMC card!\r\n"); - rt_spi_release(msd->spi_device); - - /* send dummy clock */ - { - uint8_t send_buffer[100]; - - /* initial message */ - memset(send_buffer, DUMMY, sizeof(send_buffer)); - message.send_buf = send_buffer; - message.recv_buf = RT_NULL; - message.length = sizeof(send_buffer); - message.cs_take = message.cs_release = 0; - - for (i = 0; i < 10; i++) - { - /* transfer message */ - msd->spi_device->bus->ops->xfer(msd->spi_device, &message); - } - } /* send dummy clock */ - - /* send CMD0 goto IDLE state */ - tick_start = rt_tick_get(); - while (1) - { - rt_spi_take(msd->spi_device); - result = _send_cmd(msd->spi_device, GO_IDLE_STATE, 0x00, 0x95, response_r1, response); - rt_spi_release(msd->spi_device); - - if ((result == RT_EOK) && (response[0] == MSD_IN_IDLE_STATE)) - { - break; - } - - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_TRY_TIMES))) - { - MSD_DEBUG("[err] SD card goto IDLE mode timeout!\r\n"); - result = RT_ETIMEOUT; - goto _exit; - } - } /* send CMD0 goto IDLE stat */ - - /* send CMD1 */ - tick_start = rt_tick_get(); - while (1) - { - rt_spi_take(msd->spi_device); - result = _send_cmd(msd->spi_device, SEND_OP_COND, 0x00, 0x00, response_r1, response); - rt_spi_release(msd->spi_device); - - if ((result == RT_EOK) && (response[0] == MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[info] It is MMC card!!!\r\n"); - msd->card_type = MSD_CARD_TYPE_MMC; - break; - } - - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_TRY_TIMES))) - { - MSD_DEBUG("[err] SD card goto IDLE mode timeout!\r\n"); - result = RT_ETIMEOUT; - goto _exit; - } - } /* send CMD1 */ - } /* try MMC */ - } - else if (msd->card_type == MSD_CARD_TYPE_SD_V2_X) - { - rt_spi_take(msd->spi_device); - - result = _send_cmd(msd->spi_device, READ_OCR, 0x00, 0x00, response_r3, response); - if (result != RT_EOK) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] It maybe SD2.0 But it is Not response to CMD58!\r\n"); - goto _exit; - } - - if ((response[0] & 0xFE) != 0) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] It look CMD58 as illegal command so it is not SD card!\r\n"); - result = RT_ERROR; - goto _exit; - } - - rt_spi_release(msd->spi_device); - - OCR = response[1]; - OCR = (OCR << 8) + response[2]; - OCR = (OCR << 8) + response[3]; - OCR = (OCR << 8) + response[4]; - MSD_DEBUG("[info] OCR is 0x%08X\r\n", OCR); - - if (0 == (OCR & (0x1 << 15))) - { - MSD_DEBUG(("[err] SD 1.x But not surpport current voltage\r\n")); - result = RT_ERROR; - goto _exit; - } - - /* --Send ACMD41 to make card ready */ - tick_start = rt_tick_get(); - - /* try CMD55 + ACMD41 */ - do - { - rt_spi_take(msd->spi_device); - if (rt_tick_timeout(tick_start, rt_tick_from_millisecond(CARD_TRY_TIMES_ACMD41))) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] SD Ver2.x or later try CMD55 + ACMD41 timeout!\r\n"); - result = RT_ERROR; - goto _exit; - } - - /* CMD55 APP_CMD */ - result = _send_cmd(msd->spi_device, APP_CMD, 0x00, 0x65, response_r1, response); -// if((result != RT_EOK) || (response[0] == 0x01)) - if (result != RT_EOK) - { - rt_spi_release(msd->spi_device); - continue; - } - - if ((response[0] & 0xFE) != 0) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] Not SD ready!\r\n"); - result = RT_ERROR; - goto _exit; - } - - /* ACMD41 SD_SEND_OP_COND */ - result = _send_cmd(msd->spi_device, SD_SEND_OP_COND, 0x40000000, 0x77, response_r1, response); - if (result != RT_EOK) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] ACMD41 fail!\r\n"); - result = RT_ERROR; - goto _exit; - } - - if ((response[0] & 0xFE) != 0) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[info] Not SD card4 , response : 0x%02X\r\n", response[0]); -// break; - } - } - while (response[0] != MSD_RESPONSE_NO_ERROR); - rt_spi_release(msd->spi_device); - /* try CMD55 + ACMD41 */ - - /* --Read OCR again */ - rt_spi_take(msd->spi_device); - result = _send_cmd(msd->spi_device, READ_OCR, 0x00, 0x00, response_r3, response); - if (result != RT_EOK) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] It maybe SD2.0 But it is Not response to 2nd CMD58!\r\n"); - goto _exit; - } - - if ((response[0] & 0xFE) != 0) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] It look 2nd CMD58 as illegal command so it is not SD card!\r\n"); - result = RT_ERROR; - goto _exit; - } - rt_spi_release(msd->spi_device); - - OCR = response[1]; - OCR = (OCR << 8) + response[2]; - OCR = (OCR << 8) + response[3]; - OCR = (OCR << 8) + response[4]; - MSD_DEBUG("[info] OCR 2nd read is 0x%08X\r\n", OCR); - - if ((OCR & 0x40000000) != 0) - { - MSD_DEBUG("[info] It is SD2.0 SDHC Card!!!\r\n"); - msd->card_type = MSD_CARD_TYPE_SD_SDHC; - } - else - { - MSD_DEBUG("[info] It is SD2.0 standard capacity Card!!!\r\n"); - } - } /* MSD_CARD_TYPE_SD_V2_X */ - else - { - MSD_DEBUG("[err] SD card type unkonw!\r\n"); - result = RT_ERROR; - goto _exit; - } - } /* init SD card */ - - if (msd->card_type == MSD_CARD_TYPE_SD_SDHC) - { -#ifdef RT_USING_DEVICE_OPS - dev->ops = &msd_sdhc_ops; -#else - dev->read = rt_msd_sdhc_read; - dev->write = rt_msd_sdhc_write; -#endif - } - else - { -#ifdef RT_USING_DEVICE_OPS - dev->ops = &msd_ops; -#else - dev->read = rt_msd_read; - dev->write = rt_msd_write; -#endif - } - - /* set CRC */ - { - rt_spi_release(msd->spi_device); - rt_spi_take(msd->spi_device); -#ifdef MSD_USE_CRC - result = _send_cmd(msd->spi_device, CRC_ON_OFF, 0x01, 0x83, response_r1, response); -#else - result = _send_cmd(msd->spi_device, CRC_ON_OFF, 0x00, 0x91, response_r1, response); -#endif - rt_spi_release(msd->spi_device); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] CMD59 CRC_ON_OFF fail! response : 0x%02X\r\n", response[0]); - result = RT_ERROR; - goto _exit; - } - } /* set CRC */ - - /* CMD16 SET_BLOCKLEN */ - { - rt_spi_release(msd->spi_device); - rt_spi_take(msd->spi_device); - result = _send_cmd(msd->spi_device, SET_BLOCKLEN, SECTOR_SIZE, 0x00, response_r1, response); - rt_spi_release(msd->spi_device); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] CMD16 SET_BLOCKLEN fail! response : 0x%02X\r\n", response[0]); - result = RT_ERROR; - goto _exit; - } - msd->geometry.block_size = SECTOR_SIZE; - msd->geometry.bytes_per_sector = SECTOR_SIZE; - } - - /* read CSD */ - { - uint8_t CSD_buffer[MSD_CSD_LEN]; - - rt_spi_take(msd->spi_device); -// result = _send_cmd(msd->spi_device, SEND_CSD, 0x00, 0xAF, response_r1, response); - result = _send_cmd(msd->spi_device, SEND_CSD, 0x00, 0x00, response_r1, response); - - if (result != RT_EOK) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] CMD9 SEND_CSD timeout!\r\n"); - goto _exit; - } - - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - rt_spi_release(msd->spi_device); - MSD_DEBUG("[err] CMD9 SEND_CSD fail! response : 0x%02X\r\n", response[0]); - result = RT_ERROR; - goto _exit; - } - - result = _read_block(msd->spi_device, CSD_buffer, MSD_CSD_LEN); - rt_spi_release(msd->spi_device); - if (result != RT_EOK) - { - MSD_DEBUG("[err] read CSD fail!\r\n"); - goto _exit; - } - - /* Analyze CSD */ - { - uint8_t CSD_STRUCTURE; - uint32_t C_SIZE; - uint32_t card_capacity; - - uint8_t tmp8; - uint16_t tmp16; - uint32_t tmp32; - - /* get CSD_STRUCTURE */ - tmp8 = CSD_buffer[0] & 0xC0; /* 0b11000000 */ - CSD_STRUCTURE = tmp8 >> 6; - - /* MMC CSD Analyze. */ - if (msd->card_type == MSD_CARD_TYPE_MMC) - { - uint8_t C_SIZE_MULT; - uint8_t READ_BL_LEN; - - if (CSD_STRUCTURE > 2) - { - MSD_DEBUG("[err] bad CSD Version : %d\r\n", CSD_STRUCTURE); - result = RT_ERROR; - goto _exit; - } - - if (CSD_STRUCTURE == 0) - { - MSD_DEBUG("[info] CSD version No. 1.0\r\n"); - } - else if (CSD_STRUCTURE == 1) - { - MSD_DEBUG("[info] CSD version No. 1.1\r\n"); - } - else if (CSD_STRUCTURE == 2) - { - MSD_DEBUG("[info] CSD version No. 1.2\r\n"); - } - - /* get TRAN_SPEED 8bit [103:96] */ - tmp8 = CSD_buffer[3]; - tmp8 &= 0x03; /* [2:0] transfer rate unit.*/ - if (tmp8 == 0) - { - msd->max_clock = 100 * 1000; /* 0=100kbit/s. */ - } - else if (tmp8 == 1) - { - msd->max_clock = 1 * 1000 * 1000; /* 1=1Mbit/s. */ - } - else if (tmp8 == 2) - { - msd->max_clock = 10 * 1000 * 1000; /* 2=10Mbit/s. */ - } - else if (tmp8 == 3) - { - msd->max_clock = 100 * 1000 * 1000; /* 3=100Mbit/s. */ - } - if (tmp8 == 0) - { - MSD_DEBUG("[info] TRAN_SPEED: 0x%02X, %dkbit/s.\r\n", tmp8, msd->max_clock / 1000); - } - else - { - MSD_DEBUG("[info] TRAN_SPEED: 0x%02X, %dMbit/s.\r\n", tmp8, msd->max_clock / 1000 / 1000); - } - - /* get READ_BL_LEN 4bit [83:80] */ - tmp8 = CSD_buffer[5] & 0x0F; /* 0b00001111; */ - READ_BL_LEN = tmp8; /* 4 bit */ - MSD_DEBUG("[info] CSD : READ_BL_LEN : %d %dbyte\r\n", READ_BL_LEN, (1 << READ_BL_LEN)); - - /* get C_SIZE 12bit [73:62] */ - tmp16 = CSD_buffer[6] & 0x03; /* get [73:72] 0b00000011 */ - tmp16 = tmp16 << 8; - tmp16 += CSD_buffer[7]; /* get [71:64] */ - tmp16 = tmp16 << 2; - tmp8 = CSD_buffer[8] & 0xC0; /* get [63:62] 0b11000000 */ - tmp8 = tmp8 >> 6; - tmp16 = tmp16 + tmp8; - C_SIZE = tmp16; //12 bit - MSD_DEBUG("[info] CSD : C_SIZE : %d\r\n", C_SIZE); - - /* get C_SIZE_MULT 3bit [49:47] */ - tmp8 = CSD_buffer[9] & 0x03;//0b00000011; - tmp8 = tmp8 << 1; - tmp8 = tmp8 + ((CSD_buffer[10] & 0x80/*0b10000000*/) >> 7); - C_SIZE_MULT = tmp8; // 3 bit - MSD_DEBUG("[info] CSD : C_SIZE_MULT : %d\r\n", C_SIZE_MULT); - - /* memory capacity = BLOCKNR * BLOCK_LEN */ - /* BLOCKNR = (C_SIZE+1) * MULT */ - /* MULT = 2^(C_SIZE_MULT+2) */ - /* BLOCK_LEN = 2^READ_BL_LEN */ - card_capacity = (1 << READ_BL_LEN) * ((C_SIZE + 1) * (1 << (C_SIZE_MULT + 2))); - msd->geometry.sector_count = card_capacity / msd->geometry.bytes_per_sector; - MSD_DEBUG("[info] card capacity : %d Mbyte\r\n", card_capacity / (1024 * 1024)); - } - else /* SD CSD Analyze. */ - { - if (CSD_STRUCTURE == 0) - { - uint8_t C_SIZE_MULT; - uint8_t READ_BL_LEN; - - MSD_DEBUG("[info] CSD Version 1.0\r\n"); - - /* get TRAN_SPEED 8bit [103:96] */ - tmp8 = CSD_buffer[3]; - if (tmp8 == 0x32) - { - msd->max_clock = 1000 * 1000 * 10; /* 10Mbit/s. */ - } - else if (tmp8 == 0x5A) - { - msd->max_clock = 1000 * 1000 * 50; /* 50Mbit/s. */ - } - else - { - msd->max_clock = 1000 * 1000 * 1; /* 1Mbit/s default. */ - } - MSD_DEBUG("[info] TRAN_SPEED: 0x%02X, %dMbit/s.\r\n", tmp8, msd->max_clock / 1000 / 1000); - - /* get READ_BL_LEN 4bit [83:80] */ - tmp8 = CSD_buffer[5] & 0x0F; /* 0b00001111; */ - READ_BL_LEN = tmp8; /* 4 bit */ - MSD_DEBUG("[info] CSD : READ_BL_LEN : %d %dbyte\r\n", READ_BL_LEN, (1 << READ_BL_LEN)); - - /* get C_SIZE 12bit [73:62] */ - tmp16 = CSD_buffer[6] & 0x03; /* get [73:72] 0b00000011 */ - tmp16 = tmp16 << 8; - tmp16 += CSD_buffer[7]; /* get [71:64] */ - tmp16 = tmp16 << 2; - tmp8 = CSD_buffer[8] & 0xC0; /* get [63:62] 0b11000000 */ - tmp8 = tmp8 >> 6; - tmp16 = tmp16 + tmp8; - C_SIZE = tmp16; //12 bit - MSD_DEBUG("[info] CSD : C_SIZE : %d\r\n", C_SIZE); - - /* get C_SIZE_MULT 3bit [49:47] */ - tmp8 = CSD_buffer[9] & 0x03;//0b00000011; - tmp8 = tmp8 << 1; - tmp8 = tmp8 + ((CSD_buffer[10] & 0x80/*0b10000000*/) >> 7); - C_SIZE_MULT = tmp8; // 3 bit - MSD_DEBUG("[info] CSD : C_SIZE_MULT : %d\r\n", C_SIZE_MULT); - - /* memory capacity = BLOCKNR * BLOCK_LEN */ - /* BLOCKNR = (C_SIZE+1) * MULT */ - /* MULT = 2^(C_SIZE_MULT+2) */ - /* BLOCK_LEN = 2^READ_BL_LEN */ - card_capacity = (1 << READ_BL_LEN) * ((C_SIZE + 1) * (1 << (C_SIZE_MULT + 2))); - msd->geometry.sector_count = card_capacity / msd->geometry.bytes_per_sector; - MSD_DEBUG("[info] card capacity : %d Mbyte\r\n", card_capacity / (1024 * 1024)); - } - else if (CSD_STRUCTURE == 1) - { - MSD_DEBUG("[info] CSD Version 2.0\r\n"); - - /* get TRAN_SPEED 8bit [103:96] */ - tmp8 = CSD_buffer[3]; - if (tmp8 == 0x32) - { - msd->max_clock = 1000 * 1000 * 10; /* 10Mbit/s. */ - } - else if (tmp8 == 0x5A) - { - msd->max_clock = 1000 * 1000 * 50; /* 50Mbit/s. */ - } - else if (tmp8 == 0x0B) - { - msd->max_clock = 1000 * 1000 * 100; /* 100Mbit/s. */ - /* UHS50 Card sets TRAN_SPEED to 0Bh (100Mbit/sec), */ - /* for both SDR50 and DDR50 modes. */ - } - else if (tmp8 == 0x2B) - { - msd->max_clock = 1000 * 1000 * 200; /* 200Mbit/s. */ - /* UHS104 Card sets TRAN_SPEED to 2Bh (200Mbit/sec). */ - } - else - { - msd->max_clock = 1000 * 1000 * 1; /* 1Mbit/s default. */ - } - MSD_DEBUG("[info] TRAN_SPEED: 0x%02X, %dMbit/s.\r\n", tmp8, msd->max_clock / 1000 / 1000); - - /* get C_SIZE 22bit [69:48] */ - tmp32 = CSD_buffer[7] & 0x3F; /* 0b00111111 */ - tmp32 = tmp32 << 8; - tmp32 += CSD_buffer[8]; - tmp32 = tmp32 << 8; - tmp32 += CSD_buffer[9]; - C_SIZE = tmp32; - MSD_DEBUG("[info] CSD : C_SIZE : %d\r\n", C_SIZE); - - /* memory capacity = (C_SIZE+1) * 512K byte */ - card_capacity = (C_SIZE + 1) / 2; /* unit : Mbyte */ - msd->geometry.sector_count = (C_SIZE + 1) * 1024; /* 512KB = 1024sector */ - MSD_DEBUG("[info] card capacity : %d.%d Gbyte\r\n", card_capacity / 1024, (card_capacity % 1024) * 100 / 1024); - MSD_DEBUG("[info] sector_count : %d\r\n", msd->geometry.sector_count); - } - else - { - MSD_DEBUG("[err] bad CSD Version : %d\r\n", CSD_STRUCTURE); - result = RT_ERROR; - goto _exit; - } - } /* SD CSD Analyze. */ - } /* Analyze CSD */ - - } /* read CSD */ - - /* config spi to high speed */ - { - struct rt_spi_configuration cfg; - cfg.data_width = 8; - cfg.mode = RT_SPI_MODE_0 | RT_SPI_MSB; /* SPI Compatible Modes 0 */ - cfg.max_hz = msd->max_clock; - rt_spi_configure(msd->spi_device, &cfg); - } /* config spi */ - -_exit: - rt_spi_release(msd->spi_device); - rt_mutex_release(&(msd->spi_device->bus->lock)); - return result; -} - -static rt_err_t rt_msd_open(rt_device_t dev, rt_uint16_t oflag) -{ -// struct msd_device * msd = (struct msd_device *)dev; - return RT_EOK; -} - -static rt_err_t rt_msd_close(rt_device_t dev) -{ -// struct msd_device * msd = (struct msd_device *)dev; - return RT_EOK; -} - -static rt_size_t rt_msd_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) -{ - struct msd_device *msd = (struct msd_device *)dev; - uint8_t response[MSD_RESPONSE_MAX_LEN]; - rt_err_t result = RT_EOK; - - result = MSD_take_owner(msd->spi_device); - - if (result != RT_EOK) - { - goto _exit; - } - - /* SINGLE_BLOCK? */ - if (size == 1) - { - rt_spi_take(msd->spi_device); - - result = _send_cmd(msd->spi_device, READ_SINGLE_BLOCK, pos * msd->geometry.bytes_per_sector, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] read SINGLE_BLOCK #%d fail!\r\n", pos); - size = 0; - goto _exit; - } - - result = _read_block(msd->spi_device, buffer, msd->geometry.bytes_per_sector); - if (result != RT_EOK) - { - MSD_DEBUG("[err] read SINGLE_BLOCK #%d fail!\r\n", pos); - size = 0; - } - } - else if (size > 1) - { - uint32_t i; - - rt_spi_take(msd->spi_device); - - result = _send_cmd(msd->spi_device, READ_MULTIPLE_BLOCK, pos * msd->geometry.bytes_per_sector, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK #%d fail!\r\n", pos); - size = 0; - goto _exit; - } - - for (i = 0; i < size; i++) - { - result = _read_block(msd->spi_device, - (uint8_t *)buffer + msd->geometry.bytes_per_sector * i, - msd->geometry.bytes_per_sector); - if (result != RT_EOK) - { - MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK #%d fail!\r\n", pos); - size = i; - break; - } - } - - /* send CMD12 stop transfer */ - result = _send_cmd(msd->spi_device, STOP_TRANSMISSION, 0x00, 0x00, response_r1b, response); - if (result != RT_EOK) - { - MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK, send stop token fail!\r\n"); - } - } /* READ_MULTIPLE_BLOCK */ - -_exit: - /* release and exit */ - rt_spi_release(msd->spi_device); - rt_mutex_release(&(msd->spi_device->bus->lock)); - - return size; -} - -static rt_size_t rt_msd_sdhc_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) -{ - struct msd_device *msd = (struct msd_device *)dev; - uint8_t response[MSD_RESPONSE_MAX_LEN]; - rt_err_t result = RT_EOK; - - result = MSD_take_owner(msd->spi_device); - - if (result != RT_EOK) - { - goto _exit; - } - - /* SINGLE_BLOCK? */ - if (size == 1) - { - rt_spi_take(msd->spi_device); - - result = _send_cmd(msd->spi_device, READ_SINGLE_BLOCK, pos, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] read SINGLE_BLOCK #%d fail!\r\n", pos); - size = 0; - goto _exit; - } - - result = _read_block(msd->spi_device, buffer, msd->geometry.bytes_per_sector); - if (result != RT_EOK) - { - MSD_DEBUG("[err] read SINGLE_BLOCK #%d fail!\r\n", pos); - size = 0; - } - } - else if (size > 1) - { - uint32_t i; - - rt_spi_take(msd->spi_device); - - result = _send_cmd(msd->spi_device, READ_MULTIPLE_BLOCK, pos, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK #%d fail!\r\n", pos); - size = 0; - goto _exit; - } - - for (i = 0; i < size; i++) - { - result = _read_block(msd->spi_device, - (uint8_t *)buffer + msd->geometry.bytes_per_sector * i, - msd->geometry.bytes_per_sector); - if (result != RT_EOK) - { - MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK #%d fail!\r\n", pos); - size = i; - break; - } - } - - /* send CMD12 stop transfer */ - result = _send_cmd(msd->spi_device, STOP_TRANSMISSION, 0x00, 0x00, response_r1b, response); - if (result != RT_EOK) - { - MSD_DEBUG("[err] read READ_MULTIPLE_BLOCK, send stop token fail!\r\n"); - } - } /* READ_MULTIPLE_BLOCK */ - -_exit: - /* release and exit */ - rt_spi_release(msd->spi_device); - rt_mutex_release(&(msd->spi_device->bus->lock)); - - return size; -} - -static rt_size_t rt_msd_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) -{ - struct msd_device *msd = (struct msd_device *)dev; - uint8_t response[MSD_RESPONSE_MAX_LEN]; - rt_err_t result; - - result = MSD_take_owner(msd->spi_device); - - if (result != RT_EOK) - { - MSD_DEBUG("[err] get SPI owner fail!\r\n"); - goto _exit; - } - - - /* SINGLE_BLOCK? */ - if (size == 1) - { - rt_spi_take(msd->spi_device); - result = _send_cmd(msd->spi_device, WRITE_BLOCK, pos * msd->geometry.bytes_per_sector, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] CMD WRITE_BLOCK fail!\r\n"); - size = 0; - goto _exit; - } - - result = _write_block(msd->spi_device, buffer, msd->geometry.bytes_per_sector, MSD_TOKEN_WRITE_SINGLE_START); - if (result != RT_EOK) - { - MSD_DEBUG("[err] write SINGLE_BLOCK #%d fail!\r\n", pos); - size = 0; - } - } - else if (size > 1) - { - struct rt_spi_message message; - uint32_t i; - - rt_spi_take(msd->spi_device); - -#ifdef MSD_USE_PRE_ERASED - if (msd->card_type != MSD_CARD_TYPE_MMC) - { - /* CMD55 APP_CMD */ - result = _send_cmd(msd->spi_device, APP_CMD, 0x00, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] CMD55 APP_CMD fail!\r\n"); - size = 0; - goto _exit; - } - - /* ACMD23 Pre-erased */ - result = _send_cmd(msd->spi_device, SET_WR_BLK_ERASE_COUNT, size, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] ACMD23 SET_BLOCK_COUNT fail!\r\n"); - size = 0; - goto _exit; - } - } -#endif - - result = _send_cmd(msd->spi_device, WRITE_MULTIPLE_BLOCK, pos * msd->geometry.bytes_per_sector, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] CMD WRITE_MULTIPLE_BLOCK fail!\r\n"); - size = 0; - goto _exit; - } - - /* write all block */ - for (i = 0; i < size; i++) - { - result = _write_block(msd->spi_device, - (const uint8_t *)buffer + msd->geometry.bytes_per_sector * i, - msd->geometry.bytes_per_sector, - MSD_TOKEN_WRITE_MULTIPLE_START); - if (result != RT_EOK) - { - MSD_DEBUG("[err] write SINGLE_BLOCK #%d fail!\r\n", pos); - size = i; - break; - } - } /* write all block */ - - /* send stop token */ - { - uint8_t send_buffer[18]; - - rt_memset(send_buffer, DUMMY, sizeof(send_buffer)); - send_buffer[sizeof(send_buffer) - 1] = MSD_TOKEN_WRITE_MULTIPLE_STOP; - - /* initial message */ - message.send_buf = send_buffer; - message.recv_buf = RT_NULL; - message.length = sizeof(send_buffer); - message.cs_take = message.cs_release = 0; - - /* transfer message */ - msd->spi_device->bus->ops->xfer(msd->spi_device, &message); - } - - /* wait ready */ - result = _wait_ready(msd->spi_device); - if (result != RT_EOK) - { - MSD_DEBUG("[warning] wait WRITE_MULTIPLE_BLOCK stop token ready timeout!\r\n"); - } - } /* size > 1 */ - -_exit: - /* release and exit */ - rt_spi_release(msd->spi_device); - rt_mutex_release(&(msd->spi_device->bus->lock)); - - return size; -} - -static rt_size_t rt_msd_sdhc_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) -{ - struct msd_device *msd = (struct msd_device *)dev; - uint8_t response[MSD_RESPONSE_MAX_LEN]; - rt_err_t result; - - result = MSD_take_owner(msd->spi_device); - - if (result != RT_EOK) - { - goto _exit; - } - - /* SINGLE_BLOCK? */ - if (size == 1) - { - rt_spi_take(msd->spi_device); - result = _send_cmd(msd->spi_device, WRITE_BLOCK, pos, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] CMD WRITE_BLOCK fail!\r\n"); - size = 0; - goto _exit; - } - - result = _write_block(msd->spi_device, buffer, msd->geometry.bytes_per_sector, MSD_TOKEN_WRITE_SINGLE_START); - if (result != RT_EOK) - { - MSD_DEBUG("[err] write SINGLE_BLOCK #%d fail!\r\n", pos); - size = 0; - } - } - else if (size > 1) - { - struct rt_spi_message message; - uint32_t i; - - rt_spi_take(msd->spi_device); - -#ifdef MSD_USE_PRE_ERASED - /* CMD55 APP_CMD */ - result = _send_cmd(msd->spi_device, APP_CMD, 0x00, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] CMD55 APP_CMD fail!\r\n"); - size = 0; - goto _exit; - } - - /* ACMD23 Pre-erased */ - result = _send_cmd(msd->spi_device, SET_WR_BLK_ERASE_COUNT, size, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] ACMD23 SET_BLOCK_COUNT fail!\r\n"); - size = 0; - goto _exit; - } -#endif - - result = _send_cmd(msd->spi_device, WRITE_MULTIPLE_BLOCK, pos, 0x00, response_r1, response); - if ((result != RT_EOK) || (response[0] != MSD_RESPONSE_NO_ERROR)) - { - MSD_DEBUG("[err] CMD WRITE_MULTIPLE_BLOCK fail!\r\n"); - size = 0; - goto _exit; - } - - /* write all block */ - for (i = 0; i < size; i++) - { - result = _write_block(msd->spi_device, - (const uint8_t *)buffer + msd->geometry.bytes_per_sector * i, - msd->geometry.bytes_per_sector, - MSD_TOKEN_WRITE_MULTIPLE_START); - if (result != RT_EOK) - { - MSD_DEBUG("[err] write MULTIPLE_BLOCK #%d fail!\r\n", pos); - size = i; - break; - } - } /* write all block */ - - /* send stop token */ - { - uint8_t send_buffer[18]; - - rt_memset(send_buffer, DUMMY, sizeof(send_buffer)); - send_buffer[sizeof(send_buffer) - 1] = MSD_TOKEN_WRITE_MULTIPLE_STOP; - - /* initial message */ - message.send_buf = send_buffer; - message.recv_buf = RT_NULL; - message.length = sizeof(send_buffer); - message.cs_take = message.cs_release = 0; - - /* transfer message */ - msd->spi_device->bus->ops->xfer(msd->spi_device, &message); - } - - result = _wait_ready(msd->spi_device); - if (result != RT_EOK) - { - MSD_DEBUG("[warning] wait WRITE_MULTIPLE_BLOCK stop token ready timeout!\r\n"); - } - } /* size > 1 */ - -_exit: - /* release and exit */ - rt_spi_release(msd->spi_device); - rt_mutex_release(&(msd->spi_device->bus->lock)); - - return size; -} - -static rt_err_t rt_msd_control(rt_device_t dev, int cmd, void *args) -{ - struct msd_device *msd = (struct msd_device *)dev; - - RT_ASSERT(dev != RT_NULL); - - if (cmd == RT_DEVICE_CTRL_BLK_GETGEOME) - { - struct rt_device_blk_geometry *geometry; - - geometry = (struct rt_device_blk_geometry *)args; - if (geometry == RT_NULL) return -RT_ERROR; - - geometry->bytes_per_sector = msd->geometry.bytes_per_sector; - geometry->block_size = msd->geometry.block_size; - geometry->sector_count = msd->geometry.sector_count; - } - - return RT_EOK; -} - -rt_err_t msd_init(const char *sd_device_name, const char *spi_device_name) -{ - rt_err_t result = RT_EOK; - struct rt_spi_device *spi_device; - - spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name); - if (spi_device == RT_NULL) - { - MSD_DEBUG("spi device %s not found!\r\n", spi_device_name); - return -RT_ENOSYS; - } - rt_memset(&_msd_device, 0, sizeof(_msd_device)); - _msd_device.spi_device = spi_device; - - /* register sdcard device */ - _msd_device.parent.type = RT_Device_Class_Block; - - _msd_device.geometry.bytes_per_sector = 0; - _msd_device.geometry.sector_count = 0; - _msd_device.geometry.block_size = 0; - -#ifdef RT_USING_DEVICE_OPS - _msd_device.parent.ops = &msd_ops; -#else - _msd_device.parent.init = rt_msd_init; - _msd_device.parent.open = rt_msd_open; - _msd_device.parent.close = rt_msd_close; - _msd_device.parent.read = RT_NULL; - _msd_device.parent.write = RT_NULL; - _msd_device.parent.control = rt_msd_control; -#endif - - /* no private, no callback */ - _msd_device.parent.user_data = RT_NULL; - _msd_device.parent.rx_indicate = RT_NULL; - _msd_device.parent.tx_complete = RT_NULL; - - result = rt_device_register(&_msd_device.parent, sd_device_name, - RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE | RT_DEVICE_FLAG_STANDALONE); - - return result; -} diff --git a/IoTGateWay/components/drivers/spi/spi_msd.h b/IoTGateWay/components/drivers/spi/spi_msd.h deleted file mode 100644 index 63701709237d5..0000000000000 --- a/IoTGateWay/components/drivers/spi/spi_msd.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (c) 2006-2018, RT-Thread Development Team - * - * SPDX-License-Identifier: Apache-2.0 - * - * Change Logs: - * Date Author Notes - * 2009-04-17 Bernard first version. - */ - -#ifndef SPI_MSD_H_INCLUDED -#define SPI_MSD_H_INCLUDED - -#include -#include - -/* SD command (SPI mode) */ -#define GO_IDLE_STATE 0 /* CMD0 R1 */ -#define SEND_OP_COND 1 /* CMD1 R1 */ -#define SWITCH_FUNC 6 /* CMD6 R1 */ -#define SEND_IF_COND 8 /* CMD8 R7 */ -#define SEND_CSD 9 /* CMD9 R1 */ -#define SEND_CID 10 /* CMD10 R1 */ -#define STOP_TRANSMISSION 12 /* CMD12 R1B */ -#define SEND_STATUS 13 /* CMD13 R2 */ -#define SET_BLOCKLEN 16 /* CMD16 R1 */ -#define READ_SINGLE_BLOCK 17 /* CMD17 R1 */ -#define READ_MULTIPLE_BLOCK 18 /* CMD18 R1 */ -#define WRITE_BLOCK 24 /* CMD24 R1 */ -#define WRITE_MULTIPLE_BLOCK 25 /* CMD25 R1 */ -#define PROGRAM_CSD 27 /* CMD27 R1 */ -#define SET_WRITE_PROT 28 /* CMD28 R1B */ -#define CLR_WRITE_PROT 29 /* CMD29 R1B */ -#define SEND_WRITE_PROT 30 /* CMD30 R1 */ -#define ERASE_WR_BLK_START_ADDR 32 /* CMD32 R1 */ -#define ERASE_WR_BLK_END_ADDR 33 /* CMD33 R1 */ -#define ERASE 38 /* CMD38 R1B */ -#define LOCK_UNLOCK 42 /* CMD42 R1 */ -#define APP_CMD 55 /* CMD55 R1 */ -#define GEN_CMD 56 /* CMD56 R1 */ -#define READ_OCR 58 /* CMD58 R3 */ -#define CRC_ON_OFF 59 /* CMD59 R1 */ - -/* Application-Specific Command */ -#define SD_STATUS 13 /* ACMD13 R2 */ -#define SEND_NUM_WR_BLOCKS 22 /* ACMD22 R1 */ -#define SET_WR_BLK_ERASE_COUNT 23 /* ACMD23 R1 */ -#define SD_SEND_OP_COND 41 /* ACMD41 R1 */ -#define SET_CLR_CARD_DETECT 42 /* ACMD42 R1 */ -#define SEND_SCR 51 /* ACMD51 R1 */ - -/* Start Data tokens */ -/* Tokens (necessary because at nop/idle (and CS active) only 0xff is on the data/command line) */ -#define MSD_TOKEN_READ_START 0xFE /* Data token start byte, Start Single Block Read */ -#define MSD_TOKEN_WRITE_SINGLE_START 0xFE /* Data token start byte, Start Single Block Write */ - -#define MSD_TOKEN_WRITE_MULTIPLE_START 0xFC /* Data token start byte, Start Multiple Block Write */ -#define MSD_TOKEN_WRITE_MULTIPLE_STOP 0xFD /* Data toke stop byte, Stop Multiple Block Write */ - -/* MSD reponses and error flags */ -#define MSD_RESPONSE_NO_ERROR 0x00 -#define MSD_IN_IDLE_STATE 0x01 -#define MSD_ERASE_RESET 0x02 -#define MSD_ILLEGAL_COMMAND 0x04 -#define MSD_COM_CRC_ERROR 0x08 -#define MSD_ERASE_SEQUENCE_ERROR 0x10 -#define MSD_ADDRESS_ERROR 0x20 -#define MSD_PARAMETER_ERROR 0x40 -#define MSD_RESPONSE_FAILURE 0xFF - -/* Data response error */ -#define MSD_DATA_OK 0x05 -#define MSD_DATA_CRC_ERROR 0x0B -#define MSD_DATA_WRITE_ERROR 0x0D -#define MSD_DATA_OTHER_ERROR 0xFF -#define MSD_DATA_RESPONSE_MASK 0x1F -#define MSD_GET_DATA_RESPONSE(res) (res & MSD_DATA_RESPONSE_MASK) - -#define MSD_CMD_LEN 6 /**< command, arg and crc. */ -#define MSD_RESPONSE_MAX_LEN 5 /**< response max len */ -#define MSD_CSD_LEN 16 /**< SD crad CSD register len */ -#define SECTOR_SIZE 512 /**< sector size, default 512byte */ - -/* card try timeout, unit: ms */ -#define CARD_TRY_TIMES 3000 -#define CARD_TRY_TIMES_ACMD41 800 -#define CARD_WAIT_TOKEN_TIMES 800 - -#define MSD_USE_PRE_ERASED /**< id define MSD_USE_PRE_ERASED, before CMD25, send ACMD23 */ - -/** - * SD/MMC card type - */ -typedef enum -{ - MSD_CARD_TYPE_UNKNOWN = 0, /**< unknown */ - MSD_CARD_TYPE_MMC, /**< MultiMedia Card */ - MSD_CARD_TYPE_SD_V1_X, /**< Ver 1.X Standard Capacity SD Memory Card */ - MSD_CARD_TYPE_SD_V2_X, /**< Ver 2.00 or later Standard Capacity SD Memory Card */ - MSD_CARD_TYPE_SD_SDHC, /**< High Capacity SD Memory Card */ - MSD_CARD_TYPE_SD_SDXC, /**< later Extended Capacity SD Memory Card */ -}msd_card_type; - -typedef enum -{ - response_type_unknown = 0, - response_r1, - response_r1b, - response_r2, - response_r3, - response_r4, - response_r5, - response_r7, -}response_type; - -struct msd_device -{ - struct rt_device parent; /**< RT-Thread device struct */ - struct rt_device_blk_geometry geometry; /**< sector size, sector count */ - struct rt_spi_device * spi_device; /**< SPI interface */ - msd_card_type card_type; /**< card type: MMC SD1.x SD2.0 SDHC SDXC */ - uint32_t max_clock; /**< MAX SPI clock */ -}; - -extern rt_err_t msd_init(const char * sd_device_name, const char * spi_device_name); - -#endif // SPI_MSD_H_INCLUDED diff --git a/IoTGateWay/components/drivers/spi/spi_wifi_rw009.c b/IoTGateWay/components/drivers/spi/spi_wifi_rw009.c deleted file mode 100644 index 4ddd18ca12251..0000000000000 --- a/IoTGateWay/components/drivers/spi/spi_wifi_rw009.c +++ /dev/null @@ -1,852 +0,0 @@ -/* - * 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 - */ - -#include -#include - -#include -#include -#include -#include "lwipopts.h" - -#define WIFI_DEBUG_ON -// #define ETH_RX_DUMP -// #define ETH_TX_DUMP - -#ifdef WIFI_DEBUG_ON -#define WIFI_DEBUG rt_kprintf("[RW009] ");rt_kprintf -//#define SPI_DEBUG rt_kprintf("[SPI] ");rt_kprintf -#define SPI_DEBUG(...) -#else -#define WIFI_DEBUG(...) -#define SPI_DEBUG(...) -#endif /* #ifdef WIFI_DEBUG_ON */ - -/********************************* RW009 **************************************/ -#include "spi_wifi_rw009.h" - -/* 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) -#define MAX_SPI_BUFFER_SIZE (sizeof(struct spi_response) + MAX_SPI_PACKET_SIZE) -#define MAX_ADDR_LEN 6 - -struct rw009_wifi -{ - /* inherit from ethernet device */ - struct eth_device parent; - - struct rt_spi_device *rt_spi_device; - - /* interface address info. */ - rt_uint8_t dev_addr[MAX_ADDR_LEN]; /* hw address */ - rt_uint8_t active; - - struct rt_mempool spi_tx_mp; - struct rt_mempool spi_rx_mp; - - struct rt_mailbox spi_tx_mb; - struct rt_mailbox eth_rx_mb; - - int spi_tx_mb_pool[SPI_TX_POOL_SIZE + 1]; - int eth_rx_mb_pool[SPI_RX_POOL_SIZE + 1]; - - int rw009_cmd_mb_pool[3]; - struct rt_mailbox rw009_cmd_mb; - uint32_t last_cmd; - - ALIGN(4) - rt_uint8_t spi_tx_mempool[(sizeof(struct spi_data_packet) + 4) * SPI_TX_POOL_SIZE]; - ALIGN(4) - rt_uint8_t spi_rx_mempool[(sizeof(struct spi_data_packet) + 4) * SPI_RX_POOL_SIZE]; - - ALIGN(4) - uint8_t spi_hw_rx_buffer[MAX_SPI_BUFFER_SIZE]; - - /* status for RW009 */ - rw009_ap_info ap_info; /* AP info for conn. */ - rw009_ap_info *ap_scan; /* AP list for SCAN. */ - uint32_t ap_scan_count; -}; -static struct rw009_wifi rw009_wifi_device; -static struct rt_event spi_wifi_data_event; - -static void resp_handler(struct rw009_wifi *wifi_device, struct rw009_resp *resp) -{ - struct rw009_resp *resp_return = RT_NULL; - - switch (resp->cmd) - { - case RW009_CMD_INIT: - WIFI_DEBUG("resp_handler RW009_CMD_INIT\n"); - resp_return = (struct rw009_resp *)rt_malloc(member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_init)); //TODO: - if(resp_return == RT_NULL) break; - memcpy(resp_return, resp, member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_init)); - - WIFI_DEBUG("sn:%-*.*s\n", sizeof(resp->resp.init.sn), sizeof(resp->resp.init.sn), resp->resp.init.sn); - WIFI_DEBUG("version:%-*.*s\n", sizeof(resp->resp.init.version), sizeof(resp->resp.init.version), resp->resp.init.version); - - rt_memcpy(wifi_device->dev_addr, resp->resp.init.mac, 6); - break; - - case RW009_CMD_SCAN: - if( resp->len == sizeof(rw009_ap_info) ) - { - rw009_ap_info *ap_scan = rt_realloc(wifi_device->ap_scan, sizeof(rw009_ap_info) * (wifi_device->ap_scan_count + 1) ); - if(ap_scan != RT_NULL) - { - memcpy( &ap_scan[wifi_device->ap_scan_count], &resp->resp.ap_info, sizeof(rw009_ap_info) ); - - //dump - if(1) - { -#ifdef WIFI_DEBUG_ON - rw009_ap_info *ap_info = &resp->resp.ap_info; - WIFI_DEBUG("SCAN SSID:%-32.32s\n", ap_info->ssid); - WIFI_DEBUG("SCAN BSSID:%02X-%02X-%02X-%02X-%02X-%02X\n", - ap_info->bssid[0], - ap_info->bssid[1], - ap_info->bssid[2], - ap_info->bssid[3], - ap_info->bssid[4], - ap_info->bssid[5]); - WIFI_DEBUG("SCAN rssi:%ddBm\n", ap_info->rssi); - WIFI_DEBUG("SCAN rate:%dMbps\n", ap_info->max_data_rate/1000); - WIFI_DEBUG("SCAN channel:%d\n", ap_info->channel); - WIFI_DEBUG("SCAN security:%08X\n\n", ap_info->security); -#endif /* WIFI_DEBUG_ON */ - } - - wifi_device->ap_scan_count++; - wifi_device->ap_scan = ap_scan; - } - - return; /* wait for next ap */ - } - break; - case RW009_CMD_JOIN: - case RW009_CMD_EASY_JOIN: - WIFI_DEBUG("resp_handler RW009_CMD_EASY_JOIN\n"); - resp_return = (struct rw009_resp *)rt_malloc(member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_join)); //TODO: - if(resp_return == RT_NULL) break; - memcpy(resp_return, resp, member_offset(struct rw009_resp, resp) + sizeof(rw009_resp_join)); - - if( resp->result == 0 ) - { - memcpy(&wifi_device->ap_info, &resp_return->resp.ap_info, sizeof(rw009_resp_join)); - wifi_device->active = 1; - eth_device_linkchange(&wifi_device->parent, RT_TRUE); - } - else - { - wifi_device->active = 1; - eth_device_linkchange(&wifi_device->parent, RT_FALSE); - WIFI_DEBUG("RW009_CMD_EASY_JOIN result: %d\n", resp->result ); - } - - //dupm - if(1) - { -#ifdef WIFI_DEBUG_ON - rw009_ap_info *ap_info = &resp->resp.ap_info; - WIFI_DEBUG("JOIN SSID:%-32.32s\n", ap_info->ssid); - WIFI_DEBUG("JOIN BSSID:%02X-%02X-%02X-%02X-%02X-%02X\n", - ap_info->bssid[0], - ap_info->bssid[1], - ap_info->bssid[2], - ap_info->bssid[3], - ap_info->bssid[4], - ap_info->bssid[5]); - WIFI_DEBUG("JOIN rssi:%ddBm\n", ap_info->rssi); - WIFI_DEBUG("JOIN rate:%dMbps\n", ap_info->max_data_rate/1000); - WIFI_DEBUG("JOIN channel:%d\n", ap_info->channel); - WIFI_DEBUG("JOIN security:%08X\n\n", ap_info->security); -#endif /* WIFI_DEBUG_ON */ - } - break; - - case RW009_CMD_RSSI: - // TODO: client RSSI. - { - rw009_ap_info *ap_info = &resp->resp.ap_info; - wifi_device->ap_info.rssi = ap_info->rssi; - WIFI_DEBUG("current RSSI: %d\n", wifi_device->ap_info.rssi); - } - break; - - case RW009_CMD_SOFTAP: - { - if( resp->result == 0 ) - { - ; - wifi_device->active = 1; - eth_device_linkchange(&wifi_device->parent, RT_TRUE); - } - else - { - WIFI_DEBUG("RW009_CMD_EASY_JOIN result: %d\n", resp->result ); - } - - } - break; - - default: - WIFI_DEBUG("resp_handler %d\n", resp->cmd); - break; - } - - - if(resp->cmd == wifi_device->last_cmd) - { - rt_mb_send(&wifi_device->rw009_cmd_mb, (rt_uint32_t)resp_return); - return; - } - else - { - rt_free(resp_return); - } -} - -static rt_err_t rw009_cmd(struct rw009_wifi *wifi_device, uint32_t cmd, void *args) -{ - rt_err_t result = RT_EOK; - rt_int32_t timeout = RW009_CMD_TIMEOUT; - - struct spi_data_packet *data_packet; - struct rw009_cmd *wifi_cmd = RT_NULL; - struct rw009_resp *resp = RT_NULL; - - wifi_device->last_cmd = cmd; - - data_packet = (struct spi_data_packet *)rt_mp_alloc(&wifi_device->spi_tx_mp, RT_WAITING_FOREVER); - wifi_cmd = (struct rw009_cmd *)data_packet->buffer; - - wifi_cmd->cmd = cmd; - wifi_cmd->len = 0; - - if( cmd == RW009_CMD_INIT ) - { - wifi_cmd->len = sizeof(rw009_cmd_init); - } - else if( cmd == RW009_CMD_SCAN ) - { - wifi_cmd->len = 0; - timeout += RT_TICK_PER_SECOND*10; - - if(wifi_device->ap_scan) - { - rt_free(wifi_device->ap_scan); - wifi_device->ap_scan = RT_NULL; - wifi_device->ap_scan_count = 0; - } - } - else if( cmd == RW009_CMD_JOIN ) - { - wifi_cmd->len = sizeof(rw009_cmd_join); - } - else if( cmd == RW009_CMD_EASY_JOIN ) - { - wifi_cmd->len = sizeof(rw009_cmd_easy_join); - timeout += RT_TICK_PER_SECOND*5; - } - else if( cmd == RW009_CMD_RSSI ) - { - wifi_cmd->len = sizeof(rw009_cmd_rssi); - } - else if( cmd == RW009_CMD_SOFTAP ) - { - wifi_cmd->len = sizeof(rw009_cmd_softap); - } - else - { - WIFI_DEBUG("unkown RW009 CMD %d\n", cmd); - result = -RT_ENOSYS; - rt_mp_free(data_packet); - data_packet = RT_NULL; - } - - if(data_packet == RT_NULL) - { - goto _exit; - } - - if(wifi_cmd->len) - memcpy(&wifi_cmd->params, args, wifi_cmd->len); - - data_packet->data_type = data_type_cmd; - data_packet->data_len = member_offset(struct rw009_cmd, params) + wifi_cmd->len; - - rt_mb_send(&wifi_device->spi_tx_mb, (rt_uint32_t)data_packet); - rt_event_send(&spi_wifi_data_event, 1); - - result = rt_mb_recv(&wifi_device->rw009_cmd_mb, - (rt_uint32_t *)&resp, - timeout); - - if ( result != RT_EOK ) - { - WIFI_DEBUG("CMD %d error, resultL %d\n", cmd, result ); - } - - if(resp != RT_NULL) - result = resp->result; - -_exit: - wifi_device->last_cmd = 0; - if(resp) rt_free(resp); - return result; -} - -static rt_err_t spi_wifi_transfer(struct rw009_wifi *dev) -{ - struct pbuf *p = RT_NULL; - struct spi_cmd_request cmd; - struct spi_response resp; - - rt_err_t result; - const struct spi_data_packet *data_packet = RT_NULL; - - struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev; - struct rt_spi_device *rt_spi_device = wifi_device->rt_spi_device; - - spi_wifi_int_cmd(0); - while (spi_wifi_is_busy()); - SPI_DEBUG("sequence start!\n"); - - memset(&cmd, 0, sizeof(struct spi_cmd_request)); - cmd.magic1 = CMD_MAGIC1; - cmd.magic2 = CMD_MAGIC2; - - cmd.flag |= CMD_FLAG_MRDY; - - result = rt_mb_recv(&wifi_device->spi_tx_mb, - (rt_uint32_t *)&data_packet, - 0); - if ((result == RT_EOK) && (data_packet != RT_NULL) && (data_packet->data_len > 0)) - { - cmd.M2S_len = data_packet->data_len + member_offset(struct spi_data_packet, buffer); - //SPI_DEBUG("cmd.M2S_len = %d\n", cmd.M2S_len); - } - - rt_spi_send(rt_spi_device, &cmd, sizeof(cmd)); - while (spi_wifi_is_busy()); - - { - struct rt_spi_message message; - uint32_t max_data_len = 0; - - /* setup message */ - message.send_buf = RT_NULL; - message.recv_buf = &resp; - message.length = sizeof(resp); - message.cs_take = 1; - message.cs_release = 0; - - rt_spi_take_bus(rt_spi_device); - - /* transfer message */ - rt_spi_device->bus->ops->xfer(rt_spi_device, &message); - - if ((resp.magic1 != RESP_MAGIC1) || (resp.magic2 != RESP_MAGIC2)) - { - SPI_DEBUG("bad resp magic, abort!\n"); - goto _bad_resp_magic; - } - - if (resp.flag & RESP_FLAG_SRDY) - { - SPI_DEBUG("RESP_FLAG_SRDY\n"); - max_data_len = cmd.M2S_len; - } - - if (resp.S2M_len) - { - SPI_DEBUG("resp.S2M_len: %d\n", resp.S2M_len); - if (resp.S2M_len > MAX_SPI_PACKET_SIZE) - { - SPI_DEBUG("resp.S2M_len %d > %d(MAX_SPI_PACKET_SIZE), drop!\n", resp.S2M_len, MAX_SPI_PACKET_SIZE); - resp.S2M_len = 0;//drop - } - - if (resp.S2M_len > max_data_len) - max_data_len = resp.S2M_len; - } - - if (max_data_len == 0) - { - SPI_DEBUG("no rx or tx data!\n"); - } - - //SPI_DEBUG("max_data_len = %d\n", max_data_len); - -_bad_resp_magic: - /* setup message */ - message.send_buf = data_packet;//&tx_buffer; - message.recv_buf = wifi_device->spi_hw_rx_buffer;//&rx_buffer; - message.length = max_data_len; - message.cs_take = 0; - message.cs_release = 1; - - /* transfer message */ - rt_spi_device->bus->ops->xfer(rt_spi_device, &message); - - rt_spi_release_bus(rt_spi_device); - - if (cmd.M2S_len && (resp.flag & RESP_FLAG_SRDY)) - { - rt_mp_free((void *)data_packet); - } - - if ((resp.S2M_len) && (resp.S2M_len <= MAX_SPI_PACKET_SIZE)) - { - data_packet = (struct spi_data_packet *)wifi_device->spi_hw_rx_buffer; - if (data_packet->data_type == data_type_eth_data) - { - - if (wifi_device->active) - { - p = pbuf_alloc(PBUF_LINK, data_packet->data_len, PBUF_RAM); - pbuf_take(p, (rt_uint8_t *)data_packet->buffer, data_packet->data_len); - - rt_mb_send(&wifi_device->eth_rx_mb, (rt_uint32_t)p); - eth_device_ready((struct eth_device *)dev); - } - else - { - SPI_DEBUG("!active, RX drop.\n"); - } - } - else if (data_packet->data_type == data_type_resp) - { - SPI_DEBUG("data_type_resp\n"); - resp_handler(dev, (struct rw009_resp *)data_packet->buffer); - } - else - { - SPI_DEBUG("data_type: %d, %dbyte\n", - data_packet->data_type, - data_packet->data_len); - } - } - } - spi_wifi_int_cmd(1); - - SPI_DEBUG("sequence finish!\n\n"); - - if ((cmd.M2S_len == 0) && (resp.S2M_len == 0)) - { - return -RT_ERROR; - } - - return RT_EOK; -} - -#if defined(ETH_RX_DUMP) || defined(ETH_TX_DUMP) -static void packet_dump(const char *msg, const struct pbuf *p) -{ - const struct pbuf* q; - rt_uint32_t i,j; - rt_uint8_t *ptr = p->payload; - - rt_kprintf("%s %d byte\n", msg, p->tot_len); - - i=0; - for(q=p; q != RT_NULL; q= q->next) - { - ptr = q->payload; - - for(j=0; jlen; j++) - { - if( (i%8) == 0 ) - { - rt_kprintf(" "); - } - if( (i%16) == 0 ) - { - rt_kprintf("\r\n"); - } - rt_kprintf("%02x ",*ptr); - - i++; - ptr++; - } - } - rt_kprintf("\n\n"); -} -#endif /* dump */ - -/********************************* RT-Thread Ethernet interface begin **************************************/ -static rt_err_t rw009_wifi_init(rt_device_t dev) -{ - return RT_EOK; -} - -static rt_err_t rw009_wifi_open(rt_device_t dev, rt_uint16_t oflag) -{ - return RT_EOK; -} - -static rt_err_t rw009_wifi_close(rt_device_t dev) -{ - return RT_EOK; -} - -static rt_size_t rw009_wifi_read(rt_device_t dev, rt_off_t pos, void *buffer, rt_size_t size) -{ - rt_set_errno(-RT_ENOSYS); - return 0; -} - -static rt_size_t rw009_wifi_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size) -{ - rt_set_errno(-RT_ENOSYS); - return 0; -} - -static rt_err_t rw009_wifi_control(rt_device_t dev, int cmd, void *args) -{ - struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev; - rt_err_t result = RT_EOK; - - if (cmd == NIOCTL_GADDR) - { - memcpy(args, wifi_device->dev_addr, 6); - } - else - { - result = rw009_cmd(wifi_device, cmd, args); - } - - return result; -} - -/* transmit packet. */ -rt_err_t rw009_wifi_tx(rt_device_t dev, struct pbuf *p) -{ - rt_err_t result = RT_EOK; - struct spi_data_packet *data_packet; - struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev; - - if (!wifi_device->active) - { - WIFI_DEBUG("!active, TX drop!\n"); - return RT_EOK; - } - - /* get free tx buffer */ - data_packet = (struct spi_data_packet *)rt_mp_alloc(&wifi_device->spi_tx_mp, RT_WAITING_FOREVER); - if (data_packet != RT_NULL) - { - data_packet->data_type = data_type_eth_data; - data_packet->data_len = p->tot_len; - - pbuf_copy_partial(p, data_packet->buffer, data_packet->data_len, 0); - - rt_mb_send(&wifi_device->spi_tx_mb, (rt_uint32_t)data_packet); - rt_event_send(&spi_wifi_data_event, 1); - } - else - return -RT_ERROR; - -#ifdef ETH_TX_DUMP - packet_dump("TX dump", p); -#endif /* ETH_TX_DUMP */ - - /* Return SUCCESS */ - return result; -} - -/* reception packet. */ -struct pbuf *rw009_wifi_rx(rt_device_t dev) -{ - struct pbuf *p = RT_NULL; - struct rw009_wifi *wifi_device = (struct rw009_wifi *)dev; - - if (rt_mb_recv(&wifi_device->eth_rx_mb, (rt_uint32_t *)&p, 0) != RT_EOK) - { - return RT_NULL; - } - -#ifdef ETH_RX_DUMP - if(p) - packet_dump("RX dump", p); -#endif /* ETH_RX_DUMP */ - - return p; -} -/********************************* RT-Thread Ethernet interface end **************************************/ - -static void spi_wifi_data_thread_entry(void *parameter) -{ - rt_uint32_t e; - rt_err_t result; - - while (1) - { - /* receive first event */ - if (rt_event_recv(&spi_wifi_data_event, - 1, - RT_EVENT_FLAG_AND | RT_EVENT_FLAG_CLEAR, - RT_WAITING_FOREVER, - &e) != RT_EOK) - { - continue; - } - - result = spi_wifi_transfer(&rw009_wifi_device); - - if (result == RT_EOK) - { - rt_event_send(&spi_wifi_data_event, 1); - } - } -} - -#ifdef RT_USING_DEVICE_OPS -const static struct rt_device_ops rw009_ops = -{ - rw009_wifi_init, - rw009_wifi_open, - rw009_wifi_close, - rw009_wifi_read, - rw009_wifi_write, - rw009_wifi_control -}; -#endif - -rt_err_t rt_hw_wifi_init(const char *spi_device_name, wifi_mode_t mode) -{ - /* align and struct size check. */ - RT_ASSERT( (SPI_MAX_DATA_LEN & 0x03) == 0); - RT_ASSERT( sizeof(struct rw009_resp) <= SPI_MAX_DATA_LEN); - - memset(&rw009_wifi_device, 0, sizeof(struct rw009_wifi)); - - rw009_wifi_device.rt_spi_device = (struct rt_spi_device *)rt_device_find(spi_device_name); - - if (rw009_wifi_device.rt_spi_device == RT_NULL) - { - SPI_DEBUG("spi device %s not found!\r\n", 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 = 15 * 1000000; /* 10M */ - rt_spi_configure(rw009_wifi_device.rt_spi_device, &cfg); - } - -#ifdef RT_USING_DEVICE_OPS - rw009_wifi_device.parent.parent.ops = &rw009_ops; -#else - rw009_wifi_device.parent.parent.init = rw009_wifi_init; - rw009_wifi_device.parent.parent.open = rw009_wifi_open; - rw009_wifi_device.parent.parent.close = rw009_wifi_close; - rw009_wifi_device.parent.parent.read = rw009_wifi_read; - rw009_wifi_device.parent.parent.write = rw009_wifi_write; - rw009_wifi_device.parent.parent.control = rw009_wifi_control; -#endif - rw009_wifi_device.parent.parent.user_data = RT_NULL; - - rw009_wifi_device.parent.eth_rx = rw009_wifi_rx; - rw009_wifi_device.parent.eth_tx = rw009_wifi_tx; - - rt_mp_init(&rw009_wifi_device.spi_tx_mp, - "spi_tx", - &rw009_wifi_device.spi_tx_mempool[0], - sizeof(rw009_wifi_device.spi_tx_mempool), - sizeof(struct spi_data_packet)); - - rt_mp_init(&rw009_wifi_device.spi_rx_mp, - "spi_rx", - &rw009_wifi_device.spi_rx_mempool[0], - sizeof(rw009_wifi_device.spi_rx_mempool), - sizeof(struct spi_data_packet)); - - rt_mb_init(&rw009_wifi_device.spi_tx_mb, - "spi_tx", - &rw009_wifi_device.spi_tx_mb_pool[0], - SPI_TX_POOL_SIZE, - RT_IPC_FLAG_PRIO); - - rt_mb_init(&rw009_wifi_device.eth_rx_mb, - "eth_rx", - &rw009_wifi_device.eth_rx_mb_pool[0], - SPI_TX_POOL_SIZE, - RT_IPC_FLAG_PRIO); - - rt_mb_init(&rw009_wifi_device.rw009_cmd_mb, - "wifi_cmd", - &rw009_wifi_device.rw009_cmd_mb_pool[0], - sizeof(rw009_wifi_device.rw009_cmd_mb_pool) / 4, - RT_IPC_FLAG_PRIO); - rt_event_init(&spi_wifi_data_event, "wifi", RT_IPC_FLAG_FIFO); - - spi_wifi_hw_init(); - - { - rt_thread_t tid; - - - tid = rt_thread_create("wifi", - spi_wifi_data_thread_entry, - RT_NULL, - 2048, - RT_THREAD_PRIORITY_MAX - 2, - 20); - - if (tid != RT_NULL) - rt_thread_startup(tid); - } - - /* init: get mac address */ - { - rw009_cmd_init init; - init.mode = mode; - WIFI_DEBUG("wifi_control RW009_CMD_INIT\n"); - rw009_wifi_control((rt_device_t)&rw009_wifi_device, - RW009_CMD_INIT, - (void *)&init); // 0: firmware, 1: STA, 2:AP - - } - - /* register eth device */ - eth_device_init(&(rw009_wifi_device.parent), "w0"); - eth_device_linkchange(&rw009_wifi_device.parent, RT_FALSE); - - return RT_EOK; -} - -void spi_wifi_isr(int vector) -{ - /* enter interrupt */ - rt_interrupt_enter(); - - SPI_DEBUG("spi_wifi_isr\n"); - rt_event_send(&spi_wifi_data_event, 1); - - /* leave interrupt */ - rt_interrupt_leave(); -} - -/********************************* RW009 tools **************************************/ -rt_err_t rw009_join(const char * SSID, const char * passwd) -{ - rt_err_t result; - rt_device_t wifi_device; - rw009_cmd_easy_join easy_join; - - wifi_device = rt_device_find("w0"); - if(wifi_device == RT_NULL) - return -RT_ENOSYS; - - strncpy( easy_join.ssid, SSID, sizeof(easy_join.ssid) ); - strncpy( easy_join.passwd, passwd, sizeof(easy_join.passwd) ); - - result = rt_device_control(wifi_device, - RW009_CMD_EASY_JOIN, - (void *)&easy_join); - - return result; -} - -rt_err_t rw009_softap(const char * SSID, const char * passwd,uint32_t security,uint32_t channel) -{ - rt_err_t result; - rt_device_t wifi_device; - rw009_cmd_softap softap; - - wifi_device = rt_device_find("w0"); - if(wifi_device == RT_NULL) - return -RT_ENOSYS; - - strncpy( softap.ssid, SSID, sizeof(softap.ssid) ); - strncpy( softap.passwd, passwd, sizeof(softap.passwd) ); - - softap.security = security; - softap.channel = channel; - result = rt_device_control(wifi_device, - RW009_CMD_SOFTAP, - (void *)&softap); - - return result; -} - -int32_t rw009_rssi(void) -{ - rt_err_t result; - struct rw009_wifi * wifi_device; - - wifi_device = (struct rw009_wifi *)rt_device_find("w0"); - - if(wifi_device == RT_NULL) - return 0; - - if(wifi_device->active == 0) - return 0; - - // SCAN - result = rt_device_control((rt_device_t)wifi_device, - RW009_CMD_RSSI, - RT_NULL); - - if(result == RT_EOK) - { - return wifi_device->ap_info.rssi; - } - - return 0; -} - -#ifdef RT_USING_FINSH -#include - -static rt_err_t rw009_scan(void) -{ - rt_err_t result; - struct rw009_wifi * wifi_device; - - wifi_device = (struct rw009_wifi *)rt_device_find("w0"); - - rt_kprintf("\nCMD RW009_CMD_SCAN \n"); - result = rt_device_control((rt_device_t)wifi_device, - RW009_CMD_SCAN, - RT_NULL); - - rt_kprintf("CMD RW009_CMD_SCAN result:%d\n", result); - - if(result == RT_EOK) - { - uint32_t i; - rw009_ap_info *ap_info; - - for(i=0; iap_scan_count; i++) - { - ap_info = &wifi_device->ap_scan[i]; - rt_kprintf("AP #%02d SSID: %-32.32s\n", i, ap_info->ssid ); - } - } - - return result; -} -FINSH_FUNCTION_EXPORT(rw009_scan, SACN and list AP.); -FINSH_FUNCTION_EXPORT(rw009_join, RW009 join to AP.); -FINSH_FUNCTION_EXPORT(rw009_rssi, get RW009 current AP rssi.); - -#endif // RT_USING_FINSH diff --git a/IoTGateWay/components/drivers/spi/spi_wifi_rw009.h b/IoTGateWay/components/drivers/spi/spi_wifi_rw009.h deleted file mode 100644 index 049b0a848643b..0000000000000 --- a/IoTGateWay/components/drivers/spi/spi_wifi_rw009.h +++ /dev/null @@ -1,212 +0,0 @@ -/* - * 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 - -// little-endian -struct spi_cmd_request -{ - uint32_t flag; - uint32_t M2S_len; // master to slave data len. - uint32_t magic1; - uint32_t magic2; -}; - -#define CMD_MAGIC1 (0x67452301) -#define CMD_MAGIC2 (0xEFCDAB89) - -#define CMD_FLAG_MRDY (0x01) - -// little-endian -struct spi_response -{ - uint32_t flag; - uint32_t S2M_len; // slave to master data len. - uint32_t magic1; - uint32_t magic2; -}; - -#define RESP_FLAG_SRDY (0x01) -#define RESP_MAGIC1 (0x98BADCFE) -#define RESP_MAGIC2 (0x10325476) - -/* spi slave configure. */ -#define SPI_MAX_DATA_LEN 1520 -#define SPI_TX_POOL_SIZE 2 -#define SPI_RX_POOL_SIZE 2 - -typedef enum -{ - data_type_eth_data = 0, - data_type_cmd, - data_type_resp, - data_type_status, -} -app_data_type_typedef; - -struct spi_data_packet -{ - uint32_t data_len; - uint32_t data_type; - char buffer[SPI_MAX_DATA_LEN]; -}; - -/********************************* RW009 **************************************/ - -/* option */ -#define RW009_CMD_TIMEOUT (RT_TICK_PER_SECOND*3) -#define SSID_NAME_LENGTH_MAX (32) -#define PASSWORD_LENGTH_MAX (64) - -typedef enum -{ - MODE_STATION=0, - MODE_SOFTAP=1, -} wifi_mode_t; - -typedef struct _rw009_ap_info -{ - char ssid[SSID_NAME_LENGTH_MAX]; - uint8_t bssid[8]; // 6byte + 2byte PAD. - int rssi; /* Receive Signal Strength Indication in dBm. */ - uint32_t max_data_rate; /* Maximum data rate in kilobits/s */ - uint32_t security; /* Security type */ - uint32_t channel; /* Radio channel that the AP beacon was received on */ -} rw009_ap_info; - -typedef struct _rw009_cmd_init -{ - uint32_t mode; -} rw009_cmd_init; - -typedef struct _rw009_resp_init -{ - uint8_t mac[8]; // 6byte + 2byte PAD. - uint8_t sn[24]; // serial. - char version[16]; // firmware version. -} rw009_resp_init; - -typedef struct _rw009_cmd_easy_join -{ - char ssid[SSID_NAME_LENGTH_MAX]; - char passwd[PASSWORD_LENGTH_MAX]; -} rw009_cmd_easy_join; - -typedef struct _rw009_cmd_join -{ - uint8_t bssid[8]; // 6byte + 2byte PAD. - char passwd[PASSWORD_LENGTH_MAX]; -} rw009_cmd_join; - -typedef struct _rw009_cmd_rssi -{ - uint8_t bssid[8]; // 6byte + 2byte PAD. -} rw009_cmd_rssi; - -typedef struct _rw009_cmd_softap -{ - char ssid[SSID_NAME_LENGTH_MAX]; - char passwd[PASSWORD_LENGTH_MAX]; - - uint32_t security; /* Security type. */ - uint32_t channel; /* Radio channel that the AP beacon was received on */ -} rw009_cmd_softap; - -typedef struct _rw009_resp_join -{ - rw009_ap_info ap_info; -} rw009_resp_join; - -struct rw009_cmd -{ - uint32_t cmd; - uint32_t len; - - /** command body */ - union - { - rw009_cmd_init init; - rw009_cmd_easy_join easy_join; - rw009_cmd_join join; - rw009_cmd_rssi rssi; - rw009_cmd_softap softap; - } params; -}; - -struct rw009_resp -{ - uint32_t cmd; - uint32_t len; - - int32_t result; // result for CMD. - - /** resp Body */ - union - { - rw009_resp_init init; - rw009_ap_info ap_info; - } resp; -}; - -#define RW009_CMD_INIT 128 -#define RW009_CMD_SCAN 129 -#define RW009_CMD_JOIN 130 -#define RW009_CMD_EASY_JOIN 131 -#define RW009_CMD_RSSI 132 -#define RW009_CMD_SOFTAP 133 - -/** cond !ADDTHIS*/ -#define SHARED_ENABLED 0x00008000 -#define WPA_SECURITY 0x00200000 -#define WPA2_SECURITY 0x00400000 -#define WPS_ENABLED 0x10000000 -#define WEP_ENABLED 0x0001 -#define TKIP_ENABLED 0x0002 -#define AES_ENABLED 0x0004 -#define WSEC_SWFLAG 0x0008 -/** endcond */ -/** - * Enumeration of Wi-Fi security modes - */ -typedef enum -{ - SECURITY_OPEN = 0, /**< Open security */ - SECURITY_WEP_PSK = WEP_ENABLED, /**< WEP Security with open authentication */ - SECURITY_WEP_SHARED = ( WEP_ENABLED | SHARED_ENABLED ), /**< WEP Security with shared authentication */ - SECURITY_WPA_TKIP_PSK = ( WPA_SECURITY | TKIP_ENABLED ), /**< WPA Security with TKIP */ - SECURITY_WPA_AES_PSK = ( WPA_SECURITY | AES_ENABLED ), /**< WPA Security with AES */ - SECURITY_WPA2_AES_PSK = ( WPA2_SECURITY | AES_ENABLED ), /**< WPA2 Security with AES */ - SECURITY_WPA2_TKIP_PSK = ( WPA2_SECURITY | TKIP_ENABLED ), /**< WPA2 Security with TKIP */ - SECURITY_WPA2_MIXED_PSK = ( WPA2_SECURITY | AES_ENABLED | TKIP_ENABLED ), /**< WPA2 Security with AES & TKIP */ - - SECURITY_WPS_OPEN = WPS_ENABLED, /**< WPS with open security */ - SECURITY_WPS_SECURE = (WPS_ENABLED | AES_ENABLED), /**< WPS with AES security */ - - SECURITY_UNKNOWN = -1, /**< May be returned by scan function if security is unknown. Do not pass this to the join function! */ - - SECURITY_FORCE_32_BIT = 0x7fffffff /**< Exists only to force wiced_security_t type to 32 bits */ -} security_t; - -/* porting */ -extern void spi_wifi_hw_init(void); -extern void spi_wifi_int_cmd(rt_bool_t cmd); -extern rt_bool_t spi_wifi_is_busy(void); - -/* export API. */ -extern rt_err_t rt_hw_wifi_init(const char *spi_device_name,wifi_mode_t mode); -extern int32_t rw009_rssi(void); -extern rt_err_t rw009_join(const char * SSID, const char * passwd); -extern rt_err_t rw009_softap(const char * SSID, const char * passwd,uint32_t security,uint32_t channel); - -#endif // SPI_WIFI_H_INCLUDED