/********************/ /** MAKROS **/ /********************/ #define OMD_CHIP_SELECT_ENABLE() NRF_GPIO->OUTCLR = (1UL<OUTSET = (1UL<OUTCLR = (1UL<OUTCLR = (1UL<ENABLE = 0xFUL #define OMD_SPIM_DISABLE() OMD_SPI_INSTANCE->ENABLE = 0x0UL /********************/ /** INIT FUNCTIONS **/ /********************/ static void omd_init_gpio(void) { // config GPIO pins for standard drive strength with no sense capability (see nrf_gpio.h) nrf_gpio_cfg_output(OMD_SPI_CSN_PIN); // CSN -> output nrf_gpio_cfg_output(OMD_SPI_MOSI_PIN); // MOSI -> output nrf_gpio_cfg_input(OMD_SPI_MISO_PIN, NRF_GPIO_PIN_NOPULL); // MISO -> input nrf_gpio_cfg( // CLK -> output OMD_SPI_CLK_PIN, NRF_GPIO_PIN_DIR_OUTPUT, NRF_GPIO_PIN_INPUT_CONNECT, // input buffer needs to be connected for CLK output NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_S0S1, NRF_GPIO_PIN_NOSENSE); // set idle values for output pins OMD_CHIP_SELECT_DISABLE(); OMD_CLOCK_SET_IDLE(); OMD_MOSI_SET_IDLE(); } static bool omd_init_spi(void) { // disable modules with shared ressources (see nRF52832 OPS v0.6 / Table 8: Instantiation table) if(OMD_SPI_INSTANCE == NRF_SPIM0) { NRF_SPIS0->ENABLE = 0UL; NRF_TWIM0->ENABLE = 0UL; NRF_TWIS0->ENABLE = 0UL; } else if(OMD_SPI_INSTANCE == NRF_SPIM1) { NRF_SPIS1->ENABLE = 0UL; NRF_TWIM1->ENABLE = 0UL; NRF_TWIS1->ENABLE = 0UL; } else if(OMD_SPI_INSTANCE == NRF_SPIM2) { NRF_SPIS1->ENABLE = 0UL; } else { return false; // incorrect SPIM instance } // reset registers OMD_SPI_INSTANCE->INTENCLR = 0UL; // ensure that all SPIM interrupts are disabled OMD_SPI_INSTANCE->SHORTS = 0UL; // ensure that SPIM shortcuts are disabled OMD_SPI_INSTANCE->EVENTS_STOPPED = 0; OMD_SPI_INSTANCE->TASKS_STOP = 1; // ensure that SPIM is stopped OMD_SPI_INSTANCE->ENABLE = 0UL; // ensure that SPIM is disabled OMD_SPI_INSTANCE->EVENTS_STARTED = 0; // clear all pending events OMD_SPI_INSTANCE->EVENTS_ENDTX = 0; OMD_SPI_INSTANCE->EVENTS_ENDRX = 0; OMD_SPI_INSTANCE->EVENTS_END = 0; // init GPIO pins for SPI usage omd_init_gpio(); OMD_SPI_INSTANCE->PSEL.SCK = (uint32_t)OMD_SPI_CLK_PIN; // = 31 OMD_SPI_INSTANCE->PSEL.MOSI = (uint32_t)OMD_SPI_MOSI_PIN; // = 30 OMD_SPI_INSTANCE->PSEL.MISO = (uint32_t)OMD_SPI_MISO_PIN; // = 29 // config RX registers OMD_SPI_INSTANCE->RXD.MAXCNT = (uint32_t)OMD_RX_BUFFER_SIZE; // define max. RX bytes according RX buffer size OMD_SPI_INSTANCE->RXD.PTR = (uint32_t)&OMD_RX_Buffer; // set RX data pointer to the RX buffer //OMD_SPI_INSTANCE->RXD.LIST = SPIM_RXD_LIST_LIST_Msk; // Use array list // config TX registers OMD_SPI_INSTANCE->TXD.MAXCNT = (uint32_t)OMD_TX_BUFFER_SIZE; // define max. TX bytes according TX buffer size OMD_SPI_INSTANCE->TXD.PTR = (uint32_t)&OMD_TX_Buffer; // set TX data pointer to the TX buffer //OMD_SPI_INSTANCE->TXD.LIST = SPIM_TXD_LIST_LIST_Msk; // Use array list // set config registers OMD_SPI_INSTANCE->FREQUENCY = SPI_FREQUENCY_FREQUENCY_M1; OMD_SPI_INSTANCE->ORC = (uint32_t)OMD_RX_ORC_VALUE; OMD_SPI_INSTANCE->CONFIG = (uint32_t)((SPI_CONFIG_CPOL_ActiveHigh << SPI_CONFIG_CPOL_Pos)| (SPI_CONFIG_CPHA_Leading << SPI_CONFIG_CPHA_Pos)| (SPI_CONFIG_ORDER_MsbFirst << SPI_CONFIG_ORDER_Pos)); return true; } /********************/ /** ACCESS **/ /********************/ bool omd_trigger_read_data(void) { if(OMD_SPI_INSTANCE->EVENTS_STARTED != 0) { return false; // SPI already in use } // configure RX & TX Buffers (TX -> DUMMY, RX -> RX) OMD_SPI_INSTANCE->RXD.MAXCNT = (uint32_t)OMD_RX_BUFFER_SIZE; OMD_SPI_INSTANCE->RXD.PTR = (uint32_t)&OMD_RX_Buffer; OMD_SPI_INSTANCE->TXD.MAXCNT = (uint32_t)OMD_DUMMY_BUFFER_SIZE; OMD_SPI_INSTANCE->TXD.PTR = (uint32_t)&OMD_Dummy_Buffer; omd_enable_rx_interrupt(true); // enable RX interrupt OMD_SPIM_ENABLE(); // enable SPIM interface OMD_CHIP_SELECT_ENABLE(); // select OMD sensor OMD_SPI_INSTANCE->EVENTS_STARTED = 0; // clear STARTED event OMD_SPI_INSTANCE->TASKS_START = 1; // trigger START task while (OMD_SPI_INSTANCE->EVENTS_STARTED == 0) {} // wait for STARTED event <-- will never happen OMD_SPI_INSTANCE->EVENTS_STOPPED = 0; // clear STOPPED event return true; }