diff --git a/libraries/CurieMailbox/README.txt b/libraries/CurieMailbox/README.txt new file mode 100644 index 00000000..e89af393 --- /dev/null +++ b/libraries/CurieMailbox/README.txt @@ -0,0 +1,111 @@ +CurieMailbox library for Arduino/Genuino 101 + +Overview: + +This library provides access to the inter-processor mailbox that allows +interrupt-based communication between the x86 and ARC cores contained in the +Curie module (in such a transaction, the message sender is referred to as the +"source" processor, and the recipient as the destination processor). Note that +using this library to send a message to the mailbox, when there is no +application running at the destination to receive it, will cause the source +processor busy-wait indefinitely. + +Message format: + +The CurieMailbox library uses the CurieMailboxMsg class to describe a message +for the mailbox. In total, a mailbox message contains 17 bytes of data that you +can fill. Here's how you might populate a CurieMailboxMsg; + + #include "CurieMailbox.h" + CurieMailboxMsg msg; + + /* ID can be any 31-bit value */ + msg.id = 0x7FFFFF; + + /* Data payload is an array of 4 32-bit values */ + msg.data[0] = 0xDEADBEEF; + msg.data[1] = 0xCAFEBABE; + msg.data[2] = 0xFFFFFFFF; + msg.data[3] = 0x00000000; + + /* And the channel on which the message will be sent */ + msg.channel = 6; + +API reference: + + +void CurieMailbox::begin (bool master) + + Enable interrupts for the mailbox, and optionally initialise the + mailbox hardware. + +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. + + + +void CurieMailbox::enableReceive (unsigned int channel) + + Unmask interrupts for mailbox channel 'channel', allowing it to receive + messages (channels can always send, only reception has to be enabled). + +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. + + + +void CurieMailbox::disableReceive (unsigned int channel) + + Mask interrupts for mailbox channel 'channel', so that messages can no longer + be received (but they can still be sent). + +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 CurieMailbox::available (void) + + Returns the number of received mailbox messages available for reading. + +Params: + + None + + + +void CurieMailbox::put (CurieMailboxMsg msg) + + Writes the message 'msg' to the mailbox. + +Params: + + CurieMailboxMsg msg: the message to send + + + +CurieMailboxMsg CurieMailbox::get (void) + + Gets the most recently received unread message from the mailbox. + +Params: + + None. diff --git a/libraries/CurieMailbox/examples/SharedCounter/Makefile b/libraries/CurieMailbox/examples/SharedCounter/Makefile new file mode 100644 index 00000000..d23e005d --- /dev/null +++ b/libraries/CurieMailbox/examples/SharedCounter/Makefile @@ -0,0 +1,17 @@ +ifeq ("$(strip $(CODK_DIR))", "") + $(error Please set the CODK_DIR variable.) +endif + +ARDUINOSW_DIR ?= $(CODK_DIR)/arc + +current_dir = $(shell pwd) + +VERBOSE = true + +LIBDIRS = $(ARDUINOSW_DIR)/corelibs/libraries/CurieMailbox/src + +include $(ARDUINOSW_DIR)/Makefile.inc + +all: compile + +.DEFAULT_GOAL := all diff --git a/libraries/CurieMailbox/examples/SharedCounter/SharedCounter.ino b/libraries/CurieMailbox/examples/SharedCounter/SharedCounter.ino new file mode 100644 index 00000000..4e49d108 --- /dev/null +++ b/libraries/CurieMailbox/examples/SharedCounter/SharedCounter.ino @@ -0,0 +1,80 @@ +/* + * CurieMailbox: Shared Counter example + * + * Requires sample Zephyr application CurieMailbox_SharedCounter running on x86 + * core (get it from https://github.com/01org/CODK-M-X86-Samples) + * + * This example demonstrates sharing a single integer value between the x86 + * and ARC core. This sketch (ARC core) starts by sending a value of 0 using + * CurieMailbox.put(). This is received by the application running on the x86 + * core, which increments the value by 1 and sends it back via the mailbox. + * + * This sketch will read the reply, and again increment it by one and send + * it back to the x86 core through the mailbox. In this way the count value + * will increase indefinitely, with each core performing alternate increments + * and using the mailbox to pass the value in between. + * + * Copyright (c) 2016 Intel Corporation. All rights reserved. + * See the bottom of this file for the license terms. + */ + +#include "CurieMailbox.h" + +uint32_t count = 0; + +int sendChannel = 0; /* We'll send mailbox messages on this channel */ +int receiveChannel = 1; /* And receive them on this channel */ + +void setup (void) { + Serial.begin(9600); + + /* Enable the mailbox */ + CurieMailbox.begin(); + + /* Enable channel for receiving messages */ + CurieMailbox.enableReceive(receiveChannel); +} + +void loop (void) { + CurieMailboxMsg outMsg; /* This will store the message we are sending */ + CurieMailboxMsg inMsg; /* This will store the received message */ + + delay(1000); + + outMsg.id = 0; /* ID can be whatever you like */ + outMsg.data[0] = count; /* Data is an array of 4 uint32_t types */ + outMsg.channel = sendChannel; /* Sending this message to sendChannel */ + + CurieMailbox.put(outMsg); /* Send the message */ + + /* Wait for the response */ + while (CurieMailbox.available() == 0); + + /* Read the response */ + inMsg = CurieMailbox.get(); + + Serial.print("Sent '" + String(outMsg.data[0]) + "' on channel "); + Serial.print(String(outMsg.channel) + ", got reply '" + String(inMsg.data[0])); + Serial.println("' on channel " + String(inMsg.channel)); + + /* Update our count value with the value received from mailbox */ + count = inMsg.data[0] + 1; +} + +/* + * Copyright (c) 2016 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ diff --git a/libraries/CurieMailbox/examples/String/Makefile b/libraries/CurieMailbox/examples/String/Makefile new file mode 100644 index 00000000..d23e005d --- /dev/null +++ b/libraries/CurieMailbox/examples/String/Makefile @@ -0,0 +1,17 @@ +ifeq ("$(strip $(CODK_DIR))", "") + $(error Please set the CODK_DIR variable.) +endif + +ARDUINOSW_DIR ?= $(CODK_DIR)/arc + +current_dir = $(shell pwd) + +VERBOSE = true + +LIBDIRS = $(ARDUINOSW_DIR)/corelibs/libraries/CurieMailbox/src + +include $(ARDUINOSW_DIR)/Makefile.inc + +all: compile + +.DEFAULT_GOAL := all diff --git a/libraries/CurieMailbox/examples/String/String.ino b/libraries/CurieMailbox/examples/String/String.ino new file mode 100644 index 00000000..48598ba6 --- /dev/null +++ b/libraries/CurieMailbox/examples/String/String.ino @@ -0,0 +1,62 @@ +/* + * CurieMailbox: String example + * + * Requires sample Zephyr application CurieMailbox_String running on x86 core + * (Get it from https://github.com/01org/CODK-M-X86-Samples) + * + * This example demonstrates sending a short (< 16 chars) string from the x86 + * core to the ARC core. The sketch below enables mailbox channnel 0 for + * receiving messages, and for each received message prints out the channel + * payload as a string of ASCII characters. + * + * Copyright (c) 2016 Intel Corporation. All rights reserved. + * See the bottom of this file for the license terms. + */ + +#include "CurieMailbox.h" + +void setup (void) { + Serial.begin(9600); + + /* Enable the mailbox */ + CurieMailbox.begin(); + + /* Enable all channels for receiving messages */ + for (int i = 0; i < CurieMailbox.numChannels; ++i) { + CurieMailbox.enableReceive(i); + } +} + +void printMessageAsString (CurieMailboxMsg msg) +{ + char *p = (char *)msg.data; + Serial.print("Received message from channel " + String(msg.channel) + ": "); + Serial.println(String(p)); +} + +void loop (void) { + CurieMailboxMsg inMsg; /* This will store the received message */ + + while (CurieMailbox.available() > 0) { + inMsg = CurieMailbox.get(); + printMessageAsString(inMsg); + } +} + +/* + * Copyright (c) 2016 Intel Corporation. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ diff --git a/libraries/CurieMailbox/keywords.txt b/libraries/CurieMailbox/keywords.txt new file mode 100644 index 00000000..20d9b4e9 --- /dev/null +++ b/libraries/CurieMailbox/keywords.txt @@ -0,0 +1,22 @@ +####################################### +# Syntax Coloring Map CurieMailbox +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +CurieMailbox KEYWORD1 +CurieMailboxMsg KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +begin KEYWORD2 +end KEYWORD2 +enableReceive KEYWORD2 +disableReceive KEYWORD2 +available KEYWORD2 +put KEYWORD2 +get KEYWORD2 diff --git a/libraries/CurieMailbox/library.properties b/libraries/CurieMailbox/library.properties new file mode 100644 index 00000000..29f342b7 --- /dev/null +++ b/libraries/CurieMailbox/library.properties @@ -0,0 +1,11 @@ +name=CurieMailbox +version=1.0 +author=Intel +maintainer=Intel +email=erik.nyquist@intel.com +sentence=Curie Inter-Processor Mailbox Library for Arduino/Genuino 101 +paragraph= +category=Communication +url=http://makers.intel.com +architectures=arc32 +core-dependencies=arduino (>=1.6.3) diff --git a/libraries/CurieMailbox/src/CurieMailbox.cpp b/libraries/CurieMailbox/src/CurieMailbox.cpp new file mode 100644 index 00000000..09b73c08 --- /dev/null +++ b/libraries/CurieMailbox/src/CurieMailbox.cpp @@ -0,0 +1,208 @@ +#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; +} + +CurieMailboxClass CurieMailbox = CurieMailboxClass(); + +static void buf_put (CurieMailboxMsg msg) +{ + if (CurieMailbox.available() == (BUFSIZE - 1)) { + /* Full- drop the new message */ + return; + } + + buf[head] = 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; +} + +void CurieMailboxClass::enableReceive (int channel) +{ + CAP_CHAN(channel); + intmask->ss_intmask &= ~(1 << channel); +} + +void CurieMailboxClass::disableReceive (int channel) +{ + CAP_CHAN(channel); + intmask->ss_intmask |= 1 << channel; +} + +void CurieMailboxClass::begin (void) +{ + mbox_interrupts_init(false); +} + +void CurieMailboxClass::begin (bool master) +{ + mbox_interrupts_init(master); +} + +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); +} + +void CurieMailboxClass::put (CurieMailboxMsg msg) +{ + CAP_CHAN(msg.channel); + write_channel(msg); +} + +CurieMailboxMsg CurieMailboxClass::get (void) +{ + CurieMailboxMsg msg; + + if (head != tail) { + msg = buf[tail]; + tail = (tail + 1) % BUFSIZE; + } + + return msg; +} diff --git a/libraries/CurieMailbox/src/CurieMailbox.h b/libraries/CurieMailbox/src/CurieMailbox.h new file mode 100644 index 00000000..eb45e425 --- /dev/null +++ b/libraries/CurieMailbox/src/CurieMailbox.h @@ -0,0 +1,25 @@ +#ifndef _CURIEMAILBOX_H_ +#define _CURIEMAILBOX_H_ + +#include "CurieMailboxMsg.h" + +class CurieMailboxClass { +public: + const int numChannels = 8; + + CurieMailboxClass (void); + void begin (void); + void begin (bool master); + void end (void); + + void enableReceive (int channel); + void disableReceive (int channel); + + int available (void); + void put (CurieMailboxMsg msg); + CurieMailboxMsg get (void); +}; + +extern CurieMailboxClass CurieMailbox; + +#endif diff --git a/libraries/CurieMailbox/src/CurieMailboxMsg.h b/libraries/CurieMailbox/src/CurieMailboxMsg.h new file mode 100644 index 00000000..f9e887d2 --- /dev/null +++ b/libraries/CurieMailbox/src/CurieMailboxMsg.h @@ -0,0 +1,13 @@ +#ifndef _CURIEMAILBOXMSG_H_ +#define _CURIEMAILBOXMSG_H_ + +#define CHANNEL_DATA_WORDS 4 + +class CurieMailboxMsg { +public: + uint32_t data[CHANNEL_DATA_WORDS]; + uint32_t id; + int channel = 0; +}; + +#endif diff --git a/libraries/CurieSMC/examples/smcTest/smcTest.ino b/libraries/CurieSMC/examples/smcTest/smcTest.ino new file mode 100644 index 00000000..4b56df97 --- /dev/null +++ b/libraries/CurieSMC/examples/smcTest/smcTest.ino @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2016 Intel Corporation. All rights reserved. + * See the bottom of this file for the license terms. + */ + +/* + * This sketch example demonstrates a simple way to use the Shared Memory Communication library between + * the ARC and Quark cores. + * It requires that the firmware be upgraded to one that supports the Shared Memory Communication library. + * This sketch example will need to be used with the smc example built using the CODK-M tree. + * + * This sketch sends values to the Quark core which then reads those values, doubles them and sends it back to the ARC core. + * This sketch then reads those values and displays the doubled values. + */ + +#include + +void setup() +{ + Serial.begin(384000); + while(!Serial); + SMC.begin(); +} + +void loop() +{ + for(int i = 0; i < 32; i++) + { + Serial.print("writing : "); + Serial.println(i); + SMC.write(i); + } + while(SMC.availableForRead()) + { + Serial.print("data: "); + Serial.println(SMC.read()); + } + + delay(1000); +} + +/* + Copyright (c) 2016 Intel Corporation. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + diff --git a/libraries/CurieSMC/keywords.txt b/libraries/CurieSMC/keywords.txt new file mode 100644 index 00000000..74472aa0 --- /dev/null +++ b/libraries/CurieSMC/keywords.txt @@ -0,0 +1,23 @@ +####################################### +# Syntax Coloring Map For CurieSMC +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +CurieSMC KEYWORD1 + +####################################### +# Methods and Functions (KEYWORD2) +####################################### + +write KEYWORD2 +reaD KEYWORD2 +begin KEYWORD2 +end KEYWORD2 +availableForRead KEYWORD2 +availableForWrite KEYWORD2 +####################################### +# Constants (LITERAL1) +####################################### diff --git a/libraries/CurieSMC/library.properties b/libraries/CurieSMC/library.properties new file mode 100644 index 00000000..1110f35a --- /dev/null +++ b/libraries/CurieSMC/library.properties @@ -0,0 +1,9 @@ +name=CurieSMC +version=1.0 +author=Intel +maintainer=Intel +sentence=Enables passing of data between the quark and ARC cores +paragraph= +category=Communication +url= +architectures=arc32 diff --git a/libraries/CurieSMC/src/CurieSMC.cpp b/libraries/CurieSMC/src/CurieSMC.cpp new file mode 100644 index 00000000..a7ec3124 --- /dev/null +++ b/libraries/CurieSMC/src/CurieSMC.cpp @@ -0,0 +1,74 @@ + +#include "CurieSMC.h" + +CurieSMC SMC; +void CurieSMC::begin() +{ + QUARK_BUFF_HEAD = 0; + QUARK_BUFF_TAIL = 0; + QUARK_BUFF_FLAG = 2; + ARC_BUFF_HEAD = 0; + ARC_BUFF_TAIL = 0; + ARC_BUFF_FLAG = 2; +} +int CurieSMC::write(uint8_t data) +{ + //check if buffer is available + if(ARC_BUFF_FLAG == 0) + return 1; + + //lock the buffer + ARC_BUFF_FLAG = 1; + + int new_head = (int)(ARC_BUFF_HEAD+1)%SHARED_BUFFER_SIZE; + if(new_head != ARC_BUFF_TAIL) + { + ARC_BUFF[ARC_BUFF_HEAD] = data; + ARC_BUFF_HEAD = new_head; + } + else + { + ARC_BUFF_FLAG = 2; //unlock the buffer + return 2; //buffer is full + } + + ARC_BUFF_FLAG = 2; //unlock the buffer + return 0; +} + +uint8_t CurieSMC::read() +{ + //check if buffer is available + while(QUARK_BUFF_FLAG == 0); //wait for Quark core to release the buffer + + //lock the buffer + QUARK_BUFF_FLAG = 1; + + if(availableForRead()) + { + uint8_t data = QUARK_BUFF[QUARK_BUFF_TAIL]; + QUARK_BUFF_TAIL = (QUARK_BUFF_TAIL + 1) % SHARED_BUFFER_SIZE; + QUARK_BUFF_FLAG = 2; //unlock the buffer + return data; + } + else + { + QUARK_BUFF_FLAG = 2; //unlock the buffer + return 0; + } +} + +int CurieSMC::availableForWrite() +{ + int head = ARC_BUFF_HEAD; + int tail = ARC_BUFF_TAIL; + + if(head >= tail) + return SHARED_BUFFER_SIZE - head + tail - 1; + return tail - head - 1; +} + +int CurieSMC::availableForRead() +{ + return (int)(SHARED_BUFFER_SIZE + QUARK_BUFF_HEAD-QUARK_BUFF_TAIL) % SHARED_BUFFER_SIZE; +} diff --git a/libraries/CurieSMC/src/CurieSMC.h b/libraries/CurieSMC/src/CurieSMC.h new file mode 100644 index 00000000..32219239 --- /dev/null +++ b/libraries/CurieSMC/src/CurieSMC.h @@ -0,0 +1,31 @@ + +#define QUARK_BUFF shared_data->quark_to_ARC.data +#define QUARK_BUFF_HEAD shared_data->quark_to_ARC.head +#define QUARK_BUFF_TAIL shared_data->quark_to_ARC.tail +#define QUARK_BUFF_FLAG shared_data->quark_to_ARC.flag +#define ARC_BUFF shared_data->ARC_to_quark.data +#define ARC_BUFF_HEAD shared_data->ARC_to_quark.head +#define ARC_BUFF_TAIL shared_data->ARC_to_quark.tail +#define ARC_BUFF_FLAG shared_data->ARC_to_quark.flag + +#include "Arduino.h" +#include "platform.h" + +class CurieSMC +{ +public: + CurieSMC() + { + } + + void begin(); + void end(); + int write(uint8_t data); + uint8_t read(); + int availableForWrite(); + int availableForRead(); + +private: +}; + +extern CurieSMC SMC; \ No newline at end of file diff --git a/system/libarc32_arduino101/framework/include/platform.h b/system/libarc32_arduino101/framework/include/platform.h index 583fcf71..3fe25184 100644 --- a/system/libarc32_arduino101/framework/include/platform.h +++ b/system/libarc32_arduino101/framework/include/platform.h @@ -40,6 +40,7 @@ #define NUM_CPU 4 #define CDCACM_BUFFER_SIZE 256 +#define SHARED_BUFFER_SIZE 64 struct cdc_ring_buffer { @@ -62,6 +63,30 @@ struct cdc_acm_shared_data { int device_open; }; +struct shared_ring_buffer +{ + /** Ring buffer data */ + volatile uint8_t data[SHARED_BUFFER_SIZE]; + /** Ring buffer head index, modified by producer */ + volatile int head; + /** Ring buffer tail index, modified by consumer */ + volatile int tail; + + /** Buffer status + * 0 - locked by X86 core + * 1 - locked by arc core + * 2 - available to be taken by any core + **/ + volatile int flag; +}; + +struct ipm_shared_data +{ + struct shared_ring_buffer *quark_buffer; + struct shared_ring_buffer *arc_buffer; +}; + + /** * LMT / ARC global shared structure. This structure lies in the beginning of * the RAM. @@ -109,6 +134,18 @@ struct platform_shared_block_ { * The ARC core counts on QRK to find valid pointers in place. */ struct cdc_acm_shared_data * cdc_acm_buffers; + + struct cdc_acm_shared_data cdc_acm_buffers_obj; + + struct cdc_ring_buffer cdc_acm_shared_rx_buffer; + struct cdc_ring_buffer cdc_acm_shared_tx_buffer; + + struct ipm_shared_data *ipm_shared_data_ptr; + + struct ipm_shared_data ipm_shared_data_obj; + + struct shared_ring_buffer quark_to_ARC; + struct shared_ring_buffer ARC_to_quark; }; #define RAM_START 0xA8000000 diff --git a/variants/arduino_101/libarc32drv_arduino101.a b/variants/arduino_101/libarc32drv_arduino101.a index e0cb6b8e..e88b5947 100644 Binary files a/variants/arduino_101/libarc32drv_arduino101.a and b/variants/arduino_101/libarc32drv_arduino101.a differ diff --git a/variants/arduino_101/linker_scripts/flash.ld b/variants/arduino_101/linker_scripts/flash.ld index e75a7059..d506a5a4 100644 --- a/variants/arduino_101/linker_scripts/flash.ld +++ b/variants/arduino_101/linker_scripts/flash.ld @@ -40,7 +40,7 @@ OUTPUT_FORMAT("elf32-littlearc", "elf32-bigarc", "elf32-littlearc") MEMORY { FLASH (rx) : ORIGIN = 0x40034000, LENGTH = 152K - SRAM (wx) : ORIGIN = 0xa800e000, LENGTH = 24K + SRAM (wx) : ORIGIN = 0xa8000400, LENGTH = 24K DCCM (wx) : ORIGIN = 0x80000000, LENGTH = 8K }