#include "board_spo2.h" #include "spi_master.h" #define SPI_MASTER_BAUD 500000 struct spi_module spi_master_instance; struct spi_slave_inst slave; struct dma_resource dma_resource_tx; struct dma_resource dma_resource_rx; COMPILER_ALIGNED(16) DmacDescriptor dma_descriptor_tx SECTION_DMAC_DESCRIPTOR; DmacDescriptor dma_descriptor_rx SECTION_DMAC_DESCRIPTOR; static spi_master_callback_t spi_master_cb_tx; static spi_master_callback_t spi_master_cb_rx; /******************************************************************************* * DMA Interrupt Handler */ static void spi_master_callback_tx(struct dma_resource* const resource) { spi_master_cb_tx(resource->transfered_size); } static void spi_master_callback_rx(struct dma_resource* const resource) { spi_master_cb_rx(resource->transfered_size); } /******************************************************************************* * * * param void * * return void */ void spi_master_init(spi_master_callback_t cb_tx, spi_master_callback_t cb_rx) { struct spi_config config_spi_master; struct spi_slave_inst_config slave_dev_config; struct dma_resource_config config_dma; /*************************************** * SPI Master Init. (+Slave CS Pin) */ spi_slave_inst_get_config_defaults(&slave_dev_config); slave_dev_config.ss_pin = SPI_MASTER_SS_PIN; spi_attach_slave(&slave, &slave_dev_config); spi_get_config_defaults(&config_spi_master); config_spi_master.mode_specific.master.baudrate = SPI_MASTER_BAUD; config_spi_master.mux_setting = SPI_MASTER_MUX_SETTING; config_spi_master.pinmux_pad0 = SPI_MASTER_PINMUX_PAD0; config_spi_master.pinmux_pad1 = SPI_MASTER_PINMUX_PAD1; config_spi_master.pinmux_pad2 = SPI_MASTER_PINMUX_PAD2; config_spi_master.pinmux_pad3 = SPI_MASTER_PINMUX_PAD3; spi_init(&spi_master_instance, SPI_MASTER_MODULE, &config_spi_master); spi_enable(&spi_master_instance); /*************************************** * Init. DMA resource */ dma_get_config_defaults(&config_dma); config_dma.peripheral_trigger = SPI_MASTER_DMAC_ID_TX; config_dma.trigger_action = DMA_TRIGGER_ACTION_BEAT; dma_allocate(&dma_resource_tx, &config_dma); spi_master_cb_tx = cb_tx; dma_register_callback(&dma_resource_tx, spi_master_callback_tx, DMA_CALLBACK_TRANSFER_DONE); dma_enable_callback(&dma_resource_tx, DMA_CALLBACK_TRANSFER_DONE); /**************************************/ dma_get_config_defaults(&config_dma); config_dma.peripheral_trigger = SPI_MASTER_DMAC_ID_TX; config_dma.trigger_action = DMA_TRIGGER_ACTION_BEAT; dma_allocate(&dma_resource_rx, &config_dma); spi_master_cb_rx = cb_rx; dma_register_callback(&dma_resource_rx, spi_master_callback_rx, DMA_CALLBACK_TRANSFER_DONE); dma_enable_callback(&dma_resource_rx, DMA_CALLBACK_TRANSFER_DONE); // NVIC_SetPriority(SPI_MASTER_IR, 2); } /******************************************************************************* * * * param void * * return void */ bool spi_master_transfer(uint8_t *src, uint16_t length) { struct dma_descriptor_config config; if(!src || !length) return(false); /* Der letzte Befehl ist noch nicht fertig */ if(dma_is_busy(&dma_resource_tx)) return(false); /* Sende-Deskriptor vorbereiten */ dma_descriptor_get_config_defaults(&config); config.beat_size = DMA_BEAT_SIZE_BYTE; config.src_increment_enable = true; config.dst_increment_enable = false; config.block_transfer_count = length; config.source_address = (uint32_t) src + (uint32_t) length; config.destination_address = (uint32_t) (&spi_master_instance.hw->SPI.DATA.reg); /* Deskriptor zuordnen */ dma_reset_descriptor(&dma_resource_tx); dma_descriptor_create(&dma_descriptor_tx, &config); if(dma_add_descriptor(&dma_resource_tx, &dma_descriptor_tx) != STATUS_OK) return(false); /* Übertragung starten */ spi_select_slave(&spi_master_instance, &slave, true); if(dma_start_transfer_job(&dma_resource_tx) != STATUS_OK) { dma_abort_job(&dma_resource_tx); return(false); } return(true); } bool spi_master_receive(uint8_t *src, uint16_t length) { struct dma_descriptor_config config; if(!src || !length) return(false); /* Der letzte Befehl ist noch nicht fertig */ if(dma_is_busy(&dma_resource_rx)) return(false); /* Sende-Deskriptor vorbereiten */ dma_descriptor_get_config_defaults(&config); config.beat_size = DMA_BEAT_SIZE_BYTE; config.src_increment_enable = false; config.dst_increment_enable = true; config.block_transfer_count = length; config.source_address = (uint32_t) (&spi_master_instance.hw->SPI.DATA.reg); config.destination_address = (uint32_t) src + (uint32_t) length; /* Deskriptor zuordnen */ dma_reset_descriptor(&dma_resource_rx); dma_descriptor_create(&dma_descriptor_rx, &config); if(dma_add_descriptor(&dma_resource_rx, &dma_descriptor_rx) != STATUS_OK) return(false); /* Übertragung starten */ spi_select_slave(&spi_master_instance, &slave, true); if(dma_start_transfer_job(&dma_resource_rx) != STATUS_OK) { dma_abort_job(&dma_resource_rx); return(false); } return(true); }