123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449 |
- /*
- * @ : Copyright (c) 2021 Phytium Information Technology, Inc.
- *
- * SPDX-License-Identifier: Apache-2.0.
- *
- * @Date: 2021-04-25 14:01:29
- * @LastEditTime: 2021-05-26 15:42:52
- * @Description: This files is for
- *
- * @Modify History:
- * Ver Who Date Changes
- * ----- ------ -------- --------------------------------------
- */
- #include "drv_spi.h"
- #include <rtthread.h>
- #include <rtdevice.h>
- #include <string.h>
- #include "ft_spi.h"
- #include "ft_mux.h"
- #include "ft_trace.h"
- #include "ft_generic_timer.h"
- #ifdef BSP_USE_SPI
- #define DRV_DEBUG
- #define LOG_TAG "drv.spi"
- #include <drv_log.h>
- typedef void (*spi_cs_handler_t)(const rt_bool_t select);
- typedef struct
- {
- FSpi_Ctrl_t spi_ctrl;
- struct rt_spi_bus spi_bus;
- rt_uint16_t spi_cs_pin;
- spi_cs_handler_t spi_cs_handler;
- } ft2004_spi_class;
- void ft2004_spi_cs(const rt_bool_t select);
- static ft2004_spi_class spi_obj = {
- .spi_cs_handler = ft2004_spi_cs,
- .spi_ctrl = {
- .CtrlId = SPI_CTRL_ID_0,
- .DevId = SPI_DEV_ID_0,
- .IsReady = FALSE,
- .CsPin = 5, /* use pin 5 in gpio group a as cs signal pin */
- },
- };
- static const FSpi_Conf_t spi_conf[NUM_OF_SPI_CTRL] =
- {
- {
- .DevAddr = {0x00, 0x00, 0x00, 0x00},
- .DevAddrLen = SPI_4_BYTE_ADDR,
- .WorkMode = SPI_CTRL_MASTER_MODE,
- /* mode 2 CPOL = 1, CPHA = 0 */
- .Cpol = SPI_CTRL_CPOL_HIGH,
- .Cpha = SPI_CTRL_CPHA_1EDGE,
- .BaudRDiv = SPI_SCKDV_4,
- },
- {
- .DevAddr = {0x00, 0x00, 0x00, 0x00},
- .DevAddrLen = SPI_4_BYTE_ADDR,
- .WorkMode = SPI_CTRL_MASTER_MODE,
- .Cpol = SPI_CTRL_CPOL_HIGH,
- .Cpha = SPI_CTRL_CPHA_1EDGE,
- .BaudRDiv = SPI_SCKDV_MAX,
- }};
- inline static ft2004_spi_class *ft2004_spi_get_class()
- {
- return &spi_obj;
- }
- inline static FSpi_Ctrl_t *ft2004_spi_get_ctrl()
- {
- return &(ft2004_spi_get_class()->spi_ctrl);
- }
- static const FSpi_Conf_t *ft2004_lookup_conf(FT_IN FSpi_CtrlId_t CtrlId)
- {
- return &spi_conf[CtrlId];
- }
- void ft2004_spi_cs(const rt_bool_t select)
- {
- FSpi_Ctrl_t *ctrl_p = ft2004_spi_get_ctrl();
- FSpi_SelectSlave(ctrl_p, ctrl_p->DevId, (bool_t)select);
- }
- /**spi flash operations***/
- u32 ft2004_spi_transcation(const u8 tx_data, u8 *rx_data_p)
- {
- FSpi_Ctrl_t *ctrl_p = ft2004_spi_get_ctrl();
- u32 ret = ERR_SPI_OK;
- ret = FSpi_ReadWriteByte(ctrl_p, tx_data, rx_data_p);
- return ret;
- }
- /**spi flash operations***/
- static rt_err_t ft2004_spi_init(struct rt_spi_configuration *cfg)
- {
- FSpi_Ctrl_t *ctrl_p = ft2004_spi_get_ctrl();
- FSpi_DevId_t dev_id;
- u32 ret = ERR_SPI_OK;
- //RT_ASSERT(cfg != RT_NULL);
- RT_ASSERT(ctrl_p != RT_NULL);
- dev_id = ctrl_p->DevId;
- /* get spi flash default config */
- ctrl_p->Config = *(ft2004_lookup_conf(dev_id));
- /* change config according to inputs, cfg could be RT_NULL */
- /* reset ctrl block */
- ctrl_p->IsReady = FALSE;
- /* set spi pin mux */
- Ft_setSpiMux(ctrl_p->CtrlId);
- /* init spi ctrl */
- ret = FSpi_Init(ctrl_p);
- if (ERR_SPI_OK == ret)
- {
- return RT_EOK;
- }
- else
- {
- return -RT_ERROR;
- }
- }
- static rt_uint32_t spi_xfer(struct rt_spi_device *device, struct rt_spi_message *message)
- {
- rt_size_t message_length, loop;
- rt_uint8_t *recv_buf;
- const rt_uint8_t *send_buf;
- u32 tx_rx_result = ERR_SPI_OK;
- spi_cs_handler_t cs_handler = ft2004_spi_get_class()->spi_cs_handler;
- RT_ASSERT(device != RT_NULL);
- RT_ASSERT(device->bus != RT_NULL);
- RT_ASSERT(device->bus->parent.user_data != RT_NULL);
- RT_ASSERT(message != RT_NULL);
- if (message->cs_take && cs_handler)
- {
- cs_handler(TRUE);
- }
- message_length = message->length;
- recv_buf = message->recv_buf;
- send_buf = message->send_buf;
- /* handle msg */
- for (loop = 0; loop < message_length; loop++)
- {
- /* start data exchange */
- if ((message->recv_buf) && (message->send_buf))
- {
- /* need tx and rx */
- tx_rx_result |= ft2004_spi_transcation(*send_buf, recv_buf);
- send_buf++;
- recv_buf++;
- }
- else if (message->send_buf)
- {
- /* tx only */
- tx_rx_result |= ft2004_spi_transcation(*send_buf, RT_NULL);
- send_buf++;
- }
- else
- {
- /* rx only */
- tx_rx_result |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, recv_buf);
- recv_buf++;
- }
- }
- if (ERR_SPI_OK != tx_rx_result)
- {
- LOG_E("spi transfer error : 0x%x", tx_rx_result);
- message->length = 0;
- }
- else
- {
- }
- if (message->cs_release && cs_handler)
- {
- cs_handler(FALSE);
- }
- return message->length;
- }
- static rt_err_t spi_configure(struct rt_spi_device *device,
- struct rt_spi_configuration *configuration)
- {
- RT_ASSERT(device != RT_NULL);
- RT_ASSERT(configuration != RT_NULL);
- return ft2004_spi_init(configuration);
- }
- static const struct rt_spi_ops ft2004_spi_ops =
- {
- .configure = spi_configure,
- .xfer = spi_xfer,
- };
- /**
- * Attach the spi device to SPI bus, this function must be used after initialization.
- */
- rt_err_t rt_hw_spi_device_attach(const char *bus_name, const char *device_name, rt_uint16_t cs_gpio_pin)
- {
- rt_err_t result;
- struct rt_spi_device *spi_device;
- ft2004_spi_class *spi_class = ft2004_spi_get_class();
- RT_ASSERT(spi_class != RT_NULL);
- spi_device = (struct rt_spi_device *)rt_malloc(sizeof(struct rt_spi_device));
- RT_ASSERT(spi_device != RT_NULL);
- result = rt_spi_bus_attach_device(spi_device, device_name, bus_name, RT_NULL);
- LOG_I("attach result 0x%x", result);
- if (result != RT_EOK)
- {
- if (spi_device)
- {
- rt_free(spi_device);
- }
- }
- return result;
- }
- static int rt_hw_spi_bus_init(void)
- {
- rt_err_t result;
- ft2004_spi_class *spi_class = ft2004_spi_get_class();
- LOG_I("init spi ctrl");
- spi_class->spi_bus.parent.user_data = &spi_class->spi_bus;
- result = rt_spi_bus_register(&spi_class->spi_bus, SPI_BUS_NAME, &ft2004_spi_ops);
- return result;
- }
- int rt_hw_spi_init(void)
- {
- return rt_hw_spi_bus_init();
- }
- INIT_BOARD_EXPORT(rt_hw_spi_init);
- static void rthw_spi_delay(u32 delayCnt)
- {
- Ft_GenericTimer_UsDelay(delayCnt);
- }
- /************spi flash operatiosn implemented for sample test****************/
- /* definition of s25fs maunfactor id */
- typedef struct
- {
- u8 Mid;
- u8 MemoryType;
- u8 Density;
- u8 RemainBytes;
- u8 PhySectArch;
- u8 FamilyID;
- } ft2004_manuid_t;
- /* definition of cmd for s25fs */
- #define S25FS_ENABLE_WR 0x06
- #define S25FS_DISABLE_WR 0x04
- #define S25FS_READ_ID 0x9F
- #define S25FS_READ_4BYTE_ADD 0x13
- #define S25FS_ERASE_4BYTE_ADD 0x21
- #define S25FS_READ_STATUS_1 0x05
- #define S25FS_READ_FLASH_PARAM 0x5A
- static void ft2004_dump_manuid(const ft2004_manuid_t *pId)
- {
- rt_kprintf("0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x\r\n",
- pId->Mid, pId->MemoryType, pId->Density, pId->RemainBytes,
- pId->PhySectArch, pId->FamilyID);
- }
- static u32 ft2004_read_in_4byte_addr(const u32 ReadAddr, const u32 BytesToRead, u8 *pBuf)
- {
- u32 ret = ERR_SPI_OK;
- u32 loop;
- RT_ASSERT(RT_NULL != pBuf);
- ft2004_spi_cs(TRUE);
- ret |= ft2004_spi_transcation(S25FS_READ_4BYTE_ADD, RT_NULL);
- /* only 4-bytes address, MSB first */
- ret |= ft2004_spi_transcation((u8)(ReadAddr >> 24), RT_NULL);
- ret |= ft2004_spi_transcation((u8)(ReadAddr >> 16), RT_NULL);
- ret |= ft2004_spi_transcation((u8)(ReadAddr >> 8), RT_NULL);
- ret |= ft2004_spi_transcation((u8)ReadAddr, RT_NULL);
- /* read out data */
- for (loop = 0; loop < BytesToRead; loop++)
- {
- ret |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, pBuf + loop);
- if (ERR_SPI_OK != ret)
- {
- break;
- }
- }
- ft2004_spi_cs(FALSE);
- return ret;
- }
- u32 ft2004_spi_enable_wr(const bool_t enable)
- {
- u32 ret = ERR_SPI_OK;
- ft2004_spi_cs(TRUE);
- if (enable)
- {
- ret |= ft2004_spi_transcation(S25FS_ENABLE_WR, RT_NULL);
- }
- else
- {
- ret |= ft2004_spi_transcation(S25FS_DISABLE_WR, RT_NULL);
- }
- ft2004_spi_cs(FALSE);
- return ret;
- }
- u32 ft2004_erase_sector_in_4byte_addr(const u32 sector_addr)
- {
- u32 Ret = ERR_SPI_OK;
- ft2004_spi_enable_wr(TRUE);
- LOG_I("erase sector 0x%x", Ret);
- if (ERR_SPI_OK != Ret)
- {
- return Ret;
- }
- ft2004_spi_cs(TRUE);
- Ret |= ft2004_spi_transcation(S25FS_ERASE_4BYTE_ADD, RT_NULL);
- Ret |= ft2004_spi_transcation((u8)(sector_addr >> 24), RT_NULL);
- Ret |= ft2004_spi_transcation((u8)(sector_addr >> 16), RT_NULL);
- Ret |= ft2004_spi_transcation((u8)(sector_addr >> 8), RT_NULL);
- Ret |= ft2004_spi_transcation((u8)(sector_addr), RT_NULL);
- ft2004_spi_cs(FALSE);
- return Ret;
- }
- u32 ft2004_spi_read_params(const u32 Addr)
- {
- u32 Ret = ERR_SPI_OK;
- u8 dat[8] = {0};
- u32 loop;
- ft2004_spi_cs(TRUE);
- Ret |= ft2004_spi_transcation(S25FS_READ_FLASH_PARAM, RT_NULL);
- Ret |= ft2004_spi_transcation((u8)(Addr >> 16), RT_NULL);
- Ret |= ft2004_spi_transcation((u8)(Addr >> 8), RT_NULL);
- Ret |= ft2004_spi_transcation((u8)(Addr), RT_NULL);
- for (loop = 0; loop < 8; loop++)
- {
- Ret |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, dat + loop);
- rt_kprintf("%d: 0x%x", loop, *(dat + loop));
- }
- ft2004_spi_cs(FALSE);
- return Ret;
- }
- static u32 ft2004_spi_readid_for_test(ft2004_manuid_t *pId)
- {
- FSpi_Ctrl_t *ctrl_p = ft2004_spi_get_ctrl();
- u32 ret = ERR_SPI_OK;
- if (!ctrl_p->IsReady)
- {
- return ERR_SPI_NOT_READY;
- }
- RT_ASSERT(RT_NULL != pId);
- ft2004_spi_cs(TRUE);
- /* shifting the command code “90H” followed by a 24-bit address */
- ret |= ft2004_spi_transcation(S25FS_READ_ID, RT_NULL);
- /* Manufacturer ID and the Device ID are shifted out */
- ret |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, &pId->Mid);
- ret |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, &pId->MemoryType);
- ret |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, &pId->Density);
- ret |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, &pId->RemainBytes);
- ret |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, &pId->PhySectArch);
- ret |= ft2004_spi_transcation(SPI_DUMMY_TX_DATA, &pId->FamilyID);
- ft2004_spi_cs(FALSE);
- if (ERR_SPI_OK == ret)
- {
- ft2004_dump_manuid(pId);
- }
- return ret;
- }
- static void spi_9f_s25fs_sample(int argc, char *argv[])
- {
- ft2004_manuid_t dev_id;
- u32 ret = ERR_SPI_OK;
- u32 delay = SPI_TIMEOUT * 10;
- rt_kprintf("test s25fs spi flash\r\n");
- ret |= ft2004_spi_init(RT_NULL);
- ret |= ft2004_spi_readid_for_test(&dev_id);
- rt_kprintf("result is: 0x%x \r\n", ret);
- while (--delay)
- {
- rthw_spi_delay(10);
- }
- }
- MSH_CMD_EXPORT(spi_9f_s25fs_sample, "spi s25fs cmd 9fH sample");
- static u8 read_buf[256];
- static void spi_5a_s25fs_sample(int argc, char *argv[])
- {
- u32 ret = ERR_SPI_OK;
- u32 delay = SPI_TIMEOUT * 10;
- u32 read_addr = 0x0000;
- rt_kprintf("test s25fs spi flash\r\n");
- ret |= ft2004_spi_init(RT_NULL);
- ret |= ft2004_spi_read_params(read_addr);
- ret |= ft2004_read_in_4byte_addr(read_addr, 256, read_buf);
- rt_kprintf("result is: 0x%x \r\n", ret);
- while (--delay)
- {
- rthw_spi_delay(10);
- }
- }
- MSH_CMD_EXPORT(spi_5a_s25fs_sample, "spi s25fs cmd 5aH sample");
- #endif
|