SAMB11 - "platform events"

Go To Last Post
4 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've been fighting with the samb11 for a while, trying to get things working as a SPI slave.  Once I realized I needed to just replace the interrupt handlers with my own, things are working a lot better for receive - but now I find myself fighting with the timeout I have set for ble_event_task() - 20ms is an awfully long time when the SPI clock is 1MHz.

As I was continuing to poke around the examples and various *.h files, it occurred to me that THIS is what the poorly (not?) documented "platform event" stuff is for - I can send a platform event from one or both of my SPI interrupt handlers to indicate that I'm about to need to respond quickly.  (the current ISRs just put data received over SPI into a ring buffer, and transmit from a second ring buffer or send a dummy byte if that buffer is empty - but depending on what is received over SPI, I want to reply pretty quickly.

 

So, it looks like platform events will help me - but I'm unclear how much I can do in a platform event handler.  Is it running in interrupt context?  How quick do I need to be?  I looked over the implementation of platform events, and they look moderately heavyweight (in relation to sending/receiving bytes over SPI, anyway), so I wonder if I could implement the non-ISR-appropriate bits of my SPI handler in the platform event handler without worrying too much about it?

 

Anyone have any better docs on this?  (yes, I know, it's not clear they even exist.  Sigh.)

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah, sure wish there was some (any) docs on these ASF platform events.

 

I'm not using platform events, but instead have my main loop waking up from BLE event get periodically.  From what I have read, it is possible to also wake up the BLE subsystem with a platform event, but I have not tried that, as my interrupts are mostly frequency counting and self-contained.  I'm attaching my source file in case it's helpful as a reference.  In my case, I'm tracking the overall state of the device via a simple state machine, with most of the processing handled either in the main loop or a periodic AO_TIMER; otherwise, we remain in ULP sleep mode with background BLE advertising occurring periodically.  Based on this other thread, it may be possible for the ISR to wake up the main loop that's sitting on a platform_event_get() or at_ble_event_get().  Note that I use a several second timeout on at_ble_event_get() to periodically wake up the main loop and perform various housekeeping tasks, then go back to sleep to conserve power.

 

Please let me know what you learn and if you are able to get ISR to wake up the main loop via platform event triggers.

 

Rick

 

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yeah, it seems to work - at least, I increased the wait time for ble_event_task() from 20 to 99999 (it's in ms), and sending a platform event from the ISR was able to get an LED toggled from the main loop.

 

As far as what I do, I created a handler and registered it using register_ble_user_event_cb(user_event_handler) :

static void user_event_handler(void)
{
    uint16_t plf_event_type;
    uint16_t plf_event_data_len;
    uint8_t plf_event_data[16] = {0, };

    platform_event_get(&plf_event_type, plf_event_data, &plf_event_data_len);

#define BTCOMMAND_EVENT 0x66

#define BTCOMMAND_EVENT_SUBTYPE_BLAH 0
    if(plf_event_type == ((BTCOMMAND_EVENT << 8) | BTCOMMAND_EVENT_SUBTYPE_BLAH)) {
        /* event data will be empty so don't bother sending it */
        cmdbuf = spi_mw_recv();
        btcmd_process();
    } else {
        debug_printf("GOT WRONG PLATFORM EVENT TYPE: %x\r\n",
            (unsigned int)plf_event_type);
    }

}

(incidentally, anyone know who we can report an inoperative "code editor" in the forum to?  I know I've seen others complain about it)

 

In my ISR, I send the message thusly:

 

send_plf_int_msg_ind(0, BTCOMMAND_EVENT, NULL, 0);

 

...and it seems to work, in that I don't have to wait 99+ seconds for the bt_event_task() to time out.  It doesn't seem to _help_ me in my particular case, as I don't think I'm running my code any sooner than I was with a 20ms timeout. (at least, I still send a bunch of dummy bytes over SPI instead of the response I'm trying to send)

 

Keep in mind that I don't use ULP mode, though - I don't particularly need the power savings, and one time I left it enabled and was unable to reprogram the chip with a SAM-ICE!  (I worked around it some other way, I forget how, but it left a bad taste in my mouth)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's very helpful.  Thanks for sharing the code snippets.

 

Everything I've read about "platform events" talks about triggering the "application layer", so one would assume that the platform interrupt message queues a message to wake up the application and run the task that's waiting or registered on the callback.  It doesn't surprise me that's it's not anything near real-time as this doesn't appear to be an RTOS.

 

Perhaps there's a way to take a timestamp reading to determine the actual latency between ISR and app callback.