This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Parallel to Serial Converter

Hello everyone,

I write this post because I haven't been able to find a solution to a problem I'm having to implement a parallel to serial converter. I am employing the nrf52 DK device.

My scheme of the circuit is the following one:

- Inputs :    -Clock : 2 MHz signal.

                  -Flag : 150 KHz signal.

- Outputs :  - Out : Serial output.

                   - Enable: Signal that in HIGH while Out is being transmitted.

-Internal:     - Values_8 : Array of 8 bool elements (they can change).

- What do I want to do? : Every time Flag goes low to high, I have to transmit Values_8 by Out at Clock frequency. It means, each of the 8 elements of Values_8 have to be transmitted in a Clock period. 

Firstly, I am trying to transmit the information 1 bit at 2 MHz in a serial way, without Flag. However, my main problem relies on the operation frequency: I set the input pin Clock as a GPIOTE with high priority, sensing a rising edge of this pin. When the edge is sensed, it employs its event_handler where a GPIO output is set or clear regarding the value of Value_8. However, this works only for a frequency of 100 kHz. I attach a simpler code which toggle a pin when Clock goes low to high. It only works for frequencies below 100 kHz. The event is "in_pin_handler".

void in_pin_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
	
  nrf_gpio_pin_toggle(28);
}
/**
 * @brief Function for configuring: PIN_IN pin for input, PIN_OUT pin for output,
 * and configures GPIOTE to give an interrupt on pin change.
 */
static void gpio_init(void)
{
	
	
		NRF_CLOCK->TASKS_HFCLKSTART = 1;
  
    nrf_drv_gpiote_init();

	
	  nrf_gpio_cfg_output(28);
	
		nrf_gpio_cfg_sense_input(22, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW);

    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
    in_config.pull = NRF_GPIO_PIN_NOPULL;

    nrf_drv_gpiote_in_init(22, &in_config, in_pin_handler);
   
    nrf_drv_gpiote_in_event_enable(22, true);
}

/**
 * @brief Function for application main entry.
 */
int main(void)
{

		gpio_init();

    while (true)
    {
        // Do nothing.
    }
}


/** @} */

If I implement this employing GPIOTEs connection by PPI (This is the code) it correctly works at 2 MHz, however I don't know how to transmit the information of a bit to the output, I only can set, clear or toggle the output pin. I don't know how to implement an if statement, or something like that, in order to check the value (high or low) of the output pin.

static void led_blinking_setup()
{
    uint32_t compare_evt_addr;
    uint32_t gpiote_task_addr;
    nrf_ppi_channel_t ppi_channel;
    ret_code_t err_code;
	
   nrf_drv_gpiote_out_config_t config = GPIOTE_CONFIG_OUT_TASK_TOGGLE(false); //this has be configured regarding the value of a global variable
	  err_code = nrf_drv_gpiote_out_init(28, &config);
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_ppi_channel_alloc(&ppi_channel);
    APP_ERROR_CHECK(err_code);

	
    nrf_gpio_cfg_sense_input(22, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_LOW);

    nrf_drv_gpiote_in_config_t in_config = GPIOTE_CONFIG_IN_SENSE_LOTOHI(true);
    in_config.pull = NRF_GPIO_PIN_NOPULL;

    nrf_drv_gpiote_in_init(22, &in_config, NULL);
   
    nrf_drv_gpiote_in_event_enable(22, true);
	
	
 	compare_evt_addr = nrf_drv_gpiote_in_event_addr_get(22);
    gpiote_task_addr = nrf_drv_gpiote_out_task_addr_get(28);

    err_code = nrf_drv_ppi_channel_assign(ppi_channel, compare_evt_addr, gpiote_task_addr);
    APP_ERROR_CHECK(err_code);

   err_code = nrf_drv_ppi_channel_enable(ppi_channel);
   APP_ERROR_CHECK(err_code);

 	nrf_drv_gpiote_out_task_enable(28);
		
}

int main(void)
{
		
	NRF_CLOCK->TASKS_HFCLKSTART = 1;
    ret_code_t err_code;

    err_code = nrf_drv_ppi_init();
    APP_ERROR_CHECK(err_code);

    err_code = nrf_drv_gpiote_init();
    APP_ERROR_CHECK(err_code);


	led_blinking_setup();
    while (true)
    {
			__WFI();
        // Do Nothing - GPIO can be toggled without software intervention.
    }
}

I would like to know a possible solution to achieve, or an event_handler at upper frequencies, or an alternative to set/clear a GPIO pin at high frequencies driven by an external Clock and regarding a global variable (or memory) that is changing.

Thank you so much for your help.

Parents Reply Children
No Data
Related