/** * \brief Start waiting new command. */ static void spi_slave_new_command(void) { switch (gs_ul_spi_state) { case SLAVE_STATE_IDLE: case SLAVE_STATE_END: gs_ul_spi_cmd = RC_SYN; spi_slave_transfer(&gs_ul_spi_cmd, sizeof(gs_ul_spi_cmd)); break; case SLAVE_STATE_TEST: gs_ul_spi_cmd = RC_RDY; spi_slave_transfer(&gs_ul_spi_cmd, sizeof(gs_ul_spi_cmd)); break; case SLAVE_STATE_DATA: if (gs_spi_status.ul_total_block_number < gs_ul_test_block_number) { spi_slave_transfer(gs_uc_spi_buffer, COMM_BUFFER_SIZE); } break; case SLAVE_STATE_STATUS_ENTRY: gs_ul_spi_cmd = RC_RDY; spi_slave_transfer(&gs_ul_spi_cmd, sizeof(gs_ul_spi_cmd)); gs_ul_spi_state = SLAVE_STATE_STATUS; break; case SLAVE_STATE_STATUS: gs_ul_spi_cmd = RC_SYN; spi_slave_transfer(&gs_spi_status, sizeof(struct status_block_t)); gs_ul_spi_state = SLAVE_STATE_END; break; } }
/** * \brief Initialize SPI as slave. */ static void spi_slave_initialize(void) { uint32_t i; /* Reset status */ gs_spi_status.ul_total_block_number = 0; gs_spi_status.ul_total_command_number = 0; for (i = 0; i < NB_STATUS_CMD; i++) { gs_spi_status.ul_cmd_list[i] = 0; } gs_ul_spi_state = SLAVE_STATE_IDLE; gs_ul_spi_cmd = RC_SYN; puts("-I- Initialize SPI as slave \r"); /* Configure an SPI peripheral. */ spi_enable_clock(SPI_SLAVE_BASE); spi_disable(SPI_SLAVE_BASE); spi_reset(SPI_SLAVE_BASE); spi_set_slave_mode(SPI_SLAVE_BASE); spi_disable_mode_fault_detect(SPI_SLAVE_BASE); spi_set_peripheral_chip_select_value(SPI_SLAVE_BASE, SPI_CHIP_SEL); spi_set_clock_polarity(SPI_SLAVE_BASE, SPI_CHIP_SEL, SPI_CLK_POLARITY); spi_set_clock_phase(SPI_SLAVE_BASE, SPI_CHIP_SEL, SPI_CLK_PHASE); spi_set_bits_per_transfer(SPI_SLAVE_BASE, SPI_CHIP_SEL, SPI_CSR_BITS_8_BIT); spi_enable_interrupt(SPI_SLAVE_BASE, SPI_IER_RDRF); spi_enable(SPI_SLAVE_BASE); /* Start waiting command. */ spi_slave_transfer(&gs_ul_spi_cmd, sizeof(gs_ul_spi_cmd)); }
/** * \brief Interrupt handler for the SPI slave. */ void SPI_Handler(void) { uint32_t status; status = spi_read_status(SPI_SLAVE_BASE) ; if(status & SPI_SR_NSSR) { if ( status & SPI_SR_RXBUFF ) { spi_slave_transfer(gs_uc_spi_s_tbuffer, COMM_BUFFER_SIZE, gs_uc_spi_s_rbuffer, COMM_BUFFER_SIZE); } } }
/** * \brief Initialize SPI as slave. */ static void spi_slave_initialize(void) { uint32_t i; /* Get pointer to SPI slave PDC register base */ g_p_spis_pdc = spi_get_pdc_base(SPI_MASTER_BASE); puts("-I- Initialize SPI as slave \r"); for (i = 0; i < COMM_BUFFER_SIZE; i++) { gs_uc_spi_s_tbuffer[i] = i; } #if (SAMG55) /* Enable the peripheral and set SPI mode. */ flexcom_enable(BOARD_FLEXCOM_SPI); flexcom_set_opmode(BOARD_FLEXCOM_SPI, FLEXCOM_SPI); #else /* Configure an SPI peripheral. */ pmc_enable_periph_clk(SPI_ID); #endif spi_disable(SPI_SLAVE_BASE); spi_reset(SPI_SLAVE_BASE); spi_set_slave_mode(SPI_SLAVE_BASE); spi_disable_mode_fault_detect(SPI_SLAVE_BASE); spi_set_peripheral_chip_select_value(SPI_SLAVE_BASE, SPI_CHIP_SEL); spi_set_clock_polarity(SPI_SLAVE_BASE, SPI_CHIP_SEL, SPI_CLK_POLARITY); spi_set_clock_phase(SPI_SLAVE_BASE, SPI_CHIP_SEL, SPI_CLK_PHASE); spi_set_bits_per_transfer(SPI_SLAVE_BASE, SPI_CHIP_SEL, SPI_CSR_BITS_8_BIT); spi_enable(SPI_SLAVE_BASE); pdc_disable_transfer(g_p_spis_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS); spi_slave_transfer(gs_uc_spi_s_tbuffer, COMM_BUFFER_SIZE, gs_uc_spi_s_rbuffer, COMM_BUFFER_SIZE); }
/*! \brief Main function. */ int main(void) { sysclk_init(); /* Initialize the board. * The board-specific conf_board.h file contains the configuration of * the board initialization. */ board_init(); /* Config the USART_SPI in master mode. */ usart_spi_init(USART_SPI_EXAMPLE); usart_spi_setup_device(USART_SPI_EXAMPLE, &USART_SPI_DEVICE_EXAMPLE, SPI_MODE_0, USART_SPI_EXAMPLE_BAUDRATE, 0); usart_spi_enable(USART_SPI_EXAMPLE); /* Config the SPI module in slave mode. */ spi_slave_init(SPI_SLAVE_EXAMPLE, SPI_MODE_0); spi_enable(SPI_SLAVE_EXAMPLE); /* Enable global interrupt */ cpu_irq_enable(); /* Show the test result by LED. */ if (spi_usart_master_transfer() == true && spi_slave_transfer() == true) { ioport_set_pin_level(SPI_SLAVE_EXAMPLE_LED_PIN, IOPORT_PIN_LEVEL_LOW); } else { ioport_set_pin_level(SPI_SLAVE_EXAMPLE_LED_PIN, IOPORT_PIN_LEVEL_HIGH); } while (1) { /* Do nothing */ } }