Skip to content

Commit

Permalink
CurieMailbox: remove HW access code which is now in cores/arduino
Browse files Browse the repository at this point in the history
The mailbox HW initialisation now happens in cores/arduino/main.cpp.
All of the core code for accessing the mailbox HW now lives in
cores/arduino/mailbox.cpp; the CurieMailbox library is now just a wrapper
that calls the methods from mailbox.cpp, plus a ring buffer.
  • Loading branch information
eriknyquist committed May 18, 2017
1 parent c58480c commit 474cc67
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 171 deletions.
26 changes: 6 additions & 20 deletions libraries/CurieMailbox/README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,27 +34,13 @@ can fill. Here's how you might populate a CurieMailboxMsg;
API reference:


void CurieMailbox::begin (bool master)
void CurieMailbox::begin ()

Enable interrupts for the mailbox, and optionally initialise the
mailbox hardware.
Enable interrupts for the mailbox, and set up the mailbox hardware for use

Params:

bool master: flag indicating whether mailbox hardware should be initialised.
The first processor to access the mailbox should do this; if in doubt, set
to false (default is false, no initialisation).



void CurieMailbox::begin (void)

Enable interrupts for the mailbox, and do not initialise the hardware.

Params:

None.

None


void CurieMailbox::enableReceive (unsigned int channel)
Expand All @@ -77,9 +63,9 @@ void CurieMailbox::disableReceive (unsigned int channel)

Params:

int channel: integer value (0-7) representing the channel to be enabled.
If the passed value does not represent a valid channel, then the highest
channel will be used instead.
int channel: integer value between 0 and CurieMailbox.numChannels,
representing the channel to be enabled. If the passed value does not
represent a valid channel, then the highest channel will be used instead.


int CurieMailbox::available (void)
Expand Down
149 changes: 14 additions & 135 deletions libraries/CurieMailbox/src/CurieMailbox.cpp
Original file line number Diff line number Diff line change
@@ -1,52 +1,18 @@
#include "interrupt.h"
#include "scss_registers.h"
#include "CurieMailboxMsg.h"
#include "CurieMailbox.h"

#define BUFSIZE 33
#define CHANNEL_STS_MASK 0x1
#define CHANNEL_INT_MASK 0x2
#define CTRL_WORD_MASK 0x7FFFFFFF
#define CHALL_STATUS_MASK 0xFFFF
#define CHANNEL_STS_BITS (CHANNEL_STS_MASK | CHANNEL_INT_MASK)

#define CAP_CHAN(chan) chan = (chan >= CurieMailbox.numChannels) ?\
CurieMailbox.numChannels - 1 : ((chan < 0) \
? 0 : chan)

/* Mailbox channel status register */
#define IO_REG_MAILBOX_CHALL_STS (SCSS_REGISTER_BASE + 0xAC0)

static CurieMailboxMsg buf[BUFSIZE];
static volatile unsigned int head;
static unsigned int tail;

typedef struct mbox_channel mbox_channel_t;
typedef struct mbox_intmask mbox_intmask_t;

/* Represents the registers for a single mailbox channel */
struct mbox_channel {
uint32_t ctrl;
uint32_t data[CHANNEL_DATA_WORDS];
uint32_t sts;
};

/* Mailbox interrupt mask; right now we only care about the
* second byte, for SS mailbox interrupts (one bit per mailbox channel) */
struct mbox_intmask {
uint8_t lmt_intmask;
uint8_t ss_intmask;
uint8_t lmt_halt;
uint8_t ss_halt;
};

static volatile mbox_intmask_t *intmask;
static volatile mbox_channel_t *mbox;

CurieMailboxClass::CurieMailboxClass (void)
{
intmask = (mbox_intmask_t *)IO_REG_MAILBOX_INT_MASK;
mbox = (mbox_channel_t *)IO_REG_MAILBOX_BASE;
head = 0;
tail = 0;
}
Expand All @@ -64,95 +30,6 @@ static void buf_put (CurieMailboxMsg msg)
head = (head + 1) % BUFSIZE;
}

static uint16_t get_chall_sts (void)
{
return MMIO_REG_VAL(IO_REG_MAILBOX_CHALL_STS) & CHALL_STATUS_MASK;
}

static void read_channel (int channel)
{
int i;
CurieMailboxMsg msg;

/* Copy channel data into CurieMailboxMsg object */
msg.id = mbox[channel].ctrl & CTRL_WORD_MASK;
msg.channel = channel;

for (i = 0; i < CHANNEL_DATA_WORDS; ++i) {
msg.data[i] = mbox[channel].data[i];
}

/* Add CurieMailboxMsg object to buffer */
buf_put(msg);

/* Clear channel status & interrupt flags */
mbox[channel].sts |= CHANNEL_STS_BITS;
}

static void write_channel (CurieMailboxMsg msg)
{
int i;
uint32_t key;

/* Can't write if channel status flag is set */
while ((mbox[msg.channel].sts & CHANNEL_STS_MASK));

key = interrupt_lock();
/* Poplate channel payload */
mbox[msg.channel].ctrl |= (msg.id & CTRL_WORD_MASK);
for (i = 0; i < CHANNEL_DATA_WORDS; ++i) {
mbox[msg.channel].data[i] = msg.data[i];
}

/* Trigger interupt to host */
mbox[msg.channel].ctrl |= ~(CTRL_WORD_MASK);

/* Wait for HW to set the channel status bit */
while (!(mbox[msg.channel].sts & CHANNEL_STS_MASK));

/* Wait for destination processor to clear channel status bit */
while ((mbox[msg.channel].sts & CHANNEL_STS_MASK));
interrupt_unlock(key);
}

static void mbox_isr (void)
{
int i;
uint32_t sts;

sts = get_chall_sts();
/* Get channel number */
for (i = 0; i < CurieMailbox.numChannels; ++i) {
if (sts & (1 << (i * 2 + 1))) {
break;
}
}

read_channel(i);
}

static void mbox_hardware_init (void)
{
int i;

for (i = 0; i < CurieMailbox.numChannels; ++i) {
mbox[i].sts &= ~(CHANNEL_STS_BITS);
}
}

static void mbox_interrupts_init (bool master)
{
interrupt_disable(SOC_MBOX_INTERRUPT);

/* Mask SS mailbox interrupts for all channels;
* Unmasking is done by enableReceive */
intmask->ss_intmask = 0xFF;

if (master) mbox_hardware_init();
interrupt_connect(SOC_MBOX_INTERRUPT, mbox_isr);
interrupt_enable(SOC_MBOX_INTERRUPT);
}

int CurieMailboxClass::available (void)
{
return ((head + BUFSIZE) - tail) % BUFSIZE;
Expand All @@ -161,38 +38,40 @@ int CurieMailboxClass::available (void)
void CurieMailboxClass::enableReceive (int channel)
{
CAP_CHAN(channel);
intmask->ss_intmask &= ~(1 << channel);
mailbox_enable_receive(channel);
}

void CurieMailboxClass::disableReceive (int channel)
{
CAP_CHAN(channel);
intmask->ss_intmask |= 1 << channel;
mailbox_disable_receive(channel);
}

void CurieMailboxClass::begin (void)
static void mbox_isr (CurieMailboxMsg msg)
{
mbox_interrupts_init(false);
buf_put(msg);
}

void CurieMailboxClass::begin (bool master)
void CurieMailboxClass::begin (void)
{
mbox_interrupts_init(master);
/* Channel 7 is reserved for Serial */
for (int i = 0; i < NUM_MAILBOX_CHANNELS - 1; ++i) {
mailbox_register(i, mbox_isr);
}
}

void CurieMailboxClass::end (void)
{
/* Wait for all channels to be inactive */
while (get_chall_sts());

interrupt_disable(SOC_MBOX_INTERRUPT);
interrupt_disconnect(SOC_MBOX_INTERRUPT);
/* Channel 7 is reserved for Serial */
for (int i = 0; i < NUM_MAILBOX_CHANNELS - 1; ++i) {
mailbox_register(i, 0);
}
}

void CurieMailboxClass::put (CurieMailboxMsg msg)
{
CAP_CHAN(msg.channel);
write_channel(msg);
mailbox_write(msg);
}

CurieMailboxMsg CurieMailboxClass::get (void)
Expand Down
5 changes: 2 additions & 3 deletions libraries/CurieMailbox/src/CurieMailbox.h
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
#ifndef _CURIEMAILBOX_H_
#define _CURIEMAILBOX_H_

#include "CurieMailboxMsg.h"
#include "mailbox.h"

class CurieMailboxClass {
public:
const int numChannels = 8;
const int numChannels = NUM_MAILBOX_CHANNELS - 1;

CurieMailboxClass (void);
void begin (void);
void begin (bool master);
void end (void);

void enableReceive (int channel);
Expand Down
13 changes: 0 additions & 13 deletions libraries/CurieMailbox/src/CurieMailboxMsg.h

This file was deleted.

0 comments on commit 474cc67

Please sign in to comment.