Open tarakanov opened 7 years ago
Yes that is correct. I would suggest to use SCS since it is much easier to use, but it is possible to write programs for the sensor controller without using SCS. The main CPU will need to load the program into the sensor controller RAM. Suggest to look the sensor controller trainings here: ti.com/simplelinkacademy
Thank you @jonnteolsson. I've managed to write a program in SCS. ADC and event code work well in Task Testing of SCS. Now I need to include this program into Contiki. TI's Simplelink Academy described this process for TI-RTOS, but not for Contiki. What do I need to import these files into Contiki and compile it?
As far as I look through Contiki port of CC26xx, there is mechanism to interact with AUX, but I cannot find any info about including AUX application code to Contiki.
You can use SCS to generate a bare-metal code using CCS.
The integration with contiki is very straightforward.
You will see that it will generate an init code (that you can run onde anywhere on contiki) and some interrupts (that can ideally fire events in contiki to signal your application).
We have been using this for a while without any problems with contiki and with other RTOSes.
Marco Casaroli
On Wed, Dec 28, 2016 at 10:43 AM, Semyon Tarakanov <notifications@github.com
wrote:
Thank you @jonnteolsson https://github.com/jonnteolsson. I've managed to write a program in SCS. ADC and event code work well in Task Testing of SCS. Now I need to include this program into Contiki. TI's Simplelink Academy described this process for TI-RTOS, but not for Contiki. What do I need to import these files into Contiki and compile it?
As far as I look through Contiki port of CC26xx, there is mechanism to interact with AUX, but I cannot find any info about including AUX application code to Contiki.
— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/contiki-os/contiki/issues/2019#issuecomment-269472189, or mute the thread https://github.com/notifications/unsubscribe-auth/ADszaHFjy9moPwSfd4zUiZOkQhfYw29lks5rMlljgaJpZM4LVLeg .
In addition to copying the code to sensor controller RAM and starting the controller, I would suspect you also need code so the main MCU can handle events from the controller. I would also think you'd have to manipulate clocks within AUX so the controller can keep running while the rest of the chip is powered down.
Marco, did you have to do any of that clock and power manipulation?
Hello George.
In my experience, the code generated already does the lpm and clocks initialization
I need to check if there was anything we needed to change in contiki lpm code but I think we didn't.
I do not have a computer available right now for me to check. I will post some instructions on how to do it in january.
BR
On Wed, 28 Dec 2016 at 11:25 George Oikonomou notifications@github.com wrote:
In addition to copying the code to sensor controller RAM and starting the controller, I would suspect you also need code so the main MCU can handle events from the controller. I would also think you'd have to manipulate clocks within AUX so the controller can keep running while the rest of the chip is powered down.
Marco, did you have to do any of that clock and power manipulation?
— You are receiving this because you commented.
Reply to this email directly, view it on GitHub https://github.com/contiki-os/contiki/issues/2019#issuecomment-269476639, or mute the thread https://github.com/notifications/unsubscribe-auth/ADszaEI9Bcop7xjSvKmKZEYgQWan2tLnks5rMmNBgaJpZM4LVLeg .
I "sort of" integrated the SC with Contiki, but I'm experiencing some issues. I'm using the SC UART emulation code, and I'm able to only get about 6-8 chars TX'ed without corruption. Oddly enough, RX works absolutely perfect. My test code init (based on cc26xx-demo.c) looks like this: `static aux_consumer_module_t uart_aux = { NULL, AUX_WUC_SMPH_CLOCK | AUX_WUC_AIODIO0_CLOCK | AUX_WUC_AIODIO1_CLOCK | AUX_WUC_TIMER_CLOCK | AUX_WUC_ANAIF_CLOCK | AUX_WUC_TDCIF_CLOCK | AUX_WUC_OSCCTRL_CLOCK | AUX_WUC_ADI_CLOCK | AUX_WUC_TDC_CLOCK | AUX_WUC_ADC_CLOCK | AUX_WUC_REF_CLOCK };
/---------------------------------------------------------------------------/ PROCESS_THREAD(cc26xx_my_process, ev, data) {
PROCESS_BEGIN(); printf("CC26XX test v43\n"); // to be used in the alert callback for RX softuart_event = process_alloc_event();
ti_lib_sys_ctrl_power_everything();
// Stop SC. ti_lib_aon_wuc_aux_image_invalid();
// Run all clocks at full speed for now. ti_lib_prcm_inf_clock_configure_set(PRCM_CLOCK_DIV_1, PRCM_RUN_MODE); ti_lib_prcm_inf_clock_configure_set(PRCM_CLOCK_DIV_1, PRCM_SLEEP_MODE); ti_lib_prcm_inf_clock_configure_set(PRCM_CLOCK_DIV_1, PRCM_DEEP_SLEEP_MODE); // clock resources aux_ctrl_register_consumer(&uart_aux); AUXWUCClockFreqReq(AUX_WUC_CLOCK_HIFREQ); AUXWUCPowerCtrl(AUX_WUC_POWER_ACTIVE); aux_ctrl_power_up(); // AUX domain access scifOsalEnableAuxDomainAccess(); // Init SC driver scifInit(&scifDriverSetup); // Start the UART emulator scifExecuteTasksOnceNbl(BV(SCIF_UART_EMULATOR_TASK_ID)); // Enable baud rate generation scifUartSetBaudRate(9600); // my alert callback scifOsalRegisterTaskAlertCallback(&uartAlertCallback); // Enable RX (10 idle bit periods required before enabling start bit detection) scifUartSetRxFifoThr(SCIF_UART_RX_FIFO_MAX_COUNT / 2); scifUartSetRxTimeout(10 2); scifUartSetRxEnableReqIdleCount(10 2); scifUartRxEnable(1);
// Enable events (half full RX FIFO or 10 bit period timeout scifUartSetEventMask(BV_SCIF_UART_ALERT_RX_FIFO_ABOVE_THR | BV_SCIF_UART_ALERT_RX_BYTE_TIMEOUT);
scifUartTxPutChars("Hello how's everything? This is a long string\r\n",47); ` A bit more of my previous tries is on a post a did on TI's forum: https://e2e.ti.com/support/wireless_connectivity/zigbee_6lowpan_802-15-4_mac/f/158/p/567025/2088653#2088653 Any ideas of what could be killing my TX? seems like the timer used for baudrate its getting shutdown, but since I declared use of AUX_WUC_TIMER_CLOCK shouldn't it be protected?
OK, the code I posted before does indeed work like a charm for UART emulation in Contiki via the Sensor Controller. My TX issue? dying USB<->UART interface connected to the UART emulation pins; replaced it with another, even with the same chipset, and voilá! It does work flawlessly, so yes, aux_ctrl_register_consumer() does indeed prevent any powerdowns of the required clocks on the SC. I included all AUX clocks, which I think must be trimmed to what the UART code uses, but it does work.
OK. It is not so easy to do this thing. Here is my two little step. First I write the simplest program for Sensor Controller in SCS and use only Execution Code with one line of code:
gpioSetOutput(AUXIO_O_LED_DP1);
After Code Generation I take these files to Contiki (to platform/srf06-cc26xx/sensortag
directory):
scif.c
scif.h
scif_framework.c
scif_framework.h
scif_osal_none.c
scif_osal_none.h
I include them to the build by adding BOARD_SOURCEFILES += scif_framework.c scif_osal_none.c scif.c
to Makefile.sensortag
file. Then I add a process to Contiki project (I modify cc26xx-demo.c
) with this piece of code:
#include "aux-ctrl.h"
#include "scif.h"
#define BV(x) (1 << (x))
//Other code here
static aux_consumer_module_t blink_aux = {NULL, AUX_WUC_SMPH_CLOCK };
PROCESS_THREAD(cc26xx_demo_process, ev, data)
{
PROCESS_BEGIN();
printf("CC26XX demo\n");
aux_ctrl_register_consumer(&blink_aux);
scifInit(&scifDriverSetup);
scifExecuteTasksOnceNbl(BV(SCIF_BLINK_TASK_ID));
// Other code here
Then make TARGET=srf06-cc26xx BOARD_SENSORTAG=1 BOARD=sensortag/cc2650 BOARD_CONF_DEBUGGER_DEVPACK=1
. With this code, Sensortag will turn on LED (I attached the LED to DP0 of DevPack board). So I believe it is the minimal integration program.
For my second step I tried to iterate over the Execution Code with schedule. To iterate over Execution Code you need to add fwScheduleTask(1);
to schedule next iteration in one tick. The tick time is defined by Contiki by invoking selfStartRtcTicksNow(0x00010000);
The tick time is defined in brackets in 16.16 bit format. For example, 0x00010000
is 1 second.
The execution code is (and it works OK in SCS):
U16 buttonState; //attach button to DP0 of DevPack
gpioGetInputValue(AUXIO_I_BUTTON_DP0; buttonState);
if (buttonState == 1) {
gpioClearOutput(AUXIO_O_LED_DP1);
} else {
gpioSetOutput(AUXIO_O_LED_DP1);
}
fwScheduleTask(1);
Contiki project code:
#include "aux-ctrl.h"
#include "scif.h"
#define BV(x) (1 << (x))
//Other code here
static aux_consumer_module_t blink_aux = {NULL, AUX_WUC_SMPH_CLOCK };
PROCESS_THREAD(cc26xx_demo_process, ev, data)
{
PROCESS_BEGIN();
printf("CC26XX demo\n");
aux_ctrl_register_consumer(&blink_aux);
scifInit(&scifDriverSetup);
selfStartRtcTicksNow(0x00010000);
scifExecuteTasksOnceNbl(BV(SCIF_BLINK_TASK_ID));
// Other code here
This code should check button state every 1 second and light the led. But it fails. Actually, if you hit the button while powering the board, SC will see that and will light the LED. It tells that one iteration of Execution code was done. Then something happened - the code failed or schedule failed.
SCS tells that fwScheduleTask()
uses AON_RTC channel 2 in continuous compare mode to generate periodical wake-ups for the AUX. Tuning of RTC channel 2 is done via selfStartRtcTicksNow();
and it seems no problem (as from the code). Contiki uses RTC channel 0 and channel 1 (as from soc-rtc.c
). Also I believe that Execution code should iterate even without such schedule.
So I am stuck here. Has anybody succeeded with this?
hi @tarakanov, I am stuck at the same position in your previous post. I wanted to check if you had made any progress with this?
I manage to run SC image periodically. Recall, to run Execution code you need to add fwScheduleTask(1)
for one tick. The tick time is defined by Contiki by invoking selfStartRtcTicksNow(0x00010000)
. The tick time is defined in brackets in 16.16 bit format. For example, 0x00010000
is 1 second. After this setup, you need to actually start execution by calling scifStartTasksNbl(BV(SCIF_BLINK_TASK_ID))
with Task name as argument. But do not call scifExecuteTasksOnceNbl
as I mention earlier, as it will execute task once and do not setup events for the next iteration. Here is part of the Contiki code:
PROCESS_BEGIN();
printf("CC26XX demo\n");
aux_ctrl_register_consumer(&blink_aux);
scifInit(&scifDriverSetup);
scifStartRtcTicksNow(0x00010000);
scifStartTasksNbl(BV(SCIF_BLINK_TASK_ID));
But it is conflicted with the AON RTC interrupt handler in soc-rtc.c
code. RTC software timers uses RTC channel 0 and channel 1 but soc_rtc_isr()
is programmed to catch combined event from all three channels (ch0, ch1, ch2) with this command:
ti_lib_aon_rtc_combined_event_config(AON_RTC_CH0 | AON_RTC_CH1 | AON_RTC_CH2)
And when you properly configure SC image and run it first time, RTC ch2 will raise an event after tick time which will call this routine also. And this routine will disable RTC ch2 with this code:
if(ti_lib_aon_rtc_event_get(AON_RTC_CH2)) {
/* after sleep; since a rtimer is already scheduled, do nothing */
ti_lib_aon_rtc_channel_disable(AON_RTC_CH2);
HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH2;
}
I change combine event to this, and soc_rtc_isr will not handle events from ch2:
ti_lib_aon_rtc_combined_event_config(AON_RTC_CH0 | AON_RTC_CH1)
@g-oikonomou please advise here. If Contiki uses only ch0 and ch1 for timers, maybe it is good to remove all uses of ch2 from soc-rtc.c?
I manage to make an alert to Contiki via events. To alert the main core you need add fwGenAlertInterrupt(); in the Execution Task. When you initialize SC in the Contiki, you need to register callback function for this alert:
scifOsalRegisterTaskAlertCallback(scTaskAlertCallback);
scifInit(&scifDriverSetup);
Callback function will allocate event to the process (scinterrupt_test_process
in my case):
process_event_t sc_event;
void scTaskAlertCallback(void)
{
scifClearAlertIntSource();
sc_event = process_alloc_event();
process_post(&scinterrupt_test_process, sc_event, NULL);
scifAckAlertEvents();
}
Then you can identify this event by its name:
PROCESS_YIELD();
if (ev == sc_event) {
printf("Hello from SC\n");
}
sc_event = process_alloc_event();
That expression must be done only once, in the initiation code. It assigns a unique number that represents those Sensor Controller events.
Hmm ...
Is scTaskAlertCallback()
executed during an interrupt? If it is, then it must not use process_post()
. Only process_poll()
is safe for interrupt handlers.
If it is, then it must not use process_post(). Only process_poll() is safe for interrupt handlers.
I am not so sure about that, process_post()
is asynchronous. The difference is that we can raise a specific event, whereas with process_poll()
we always send the same generic "poll" event
I am not so sure about that,
process_post()
is asynchronous.
OK. I looked at the code again. Now, I think that you're right. process_post()
can "interrupt" do_event()
without causing trouble.
Thanks for your instructions @tarakanov Very Helpful! It seems like you have discovered an incompatibility of contiki with CC1350 AUX. Another way of fixing the problem is by NOT disabling RTC_CH2
if(ti_lib_aon_rtc_event_get(AON_RTC_CH2)) { / after sleep; since a rtimer is already scheduled, do nothing / // ti_lib_aon_rtc_channel_disable(AON_RTC_CH2); HWREG(AON_RTC_BASE + AON_RTC_O_EVFLAGS) = AON_RTC_EVFLAGS_CH2; }
I dug a bit deeper and found that aux_ctrl_register_consumer() triggers AONWUC_AUX_WAKEUP, which causes soc_rtc.c to disable AON_RTC_CH2. My question here is that why does contiki (soc-rtc.c) disable AON_RTC_CH2. What it is doing is killing any interrupts from the AUX, immediately after waking it up.
Which leads me to the question - Is it safe to disable AON_RTC_CH2. Does any other code in the contiki environment use it?
Hi! I would like to write sensor handling program for Sensor Controller (AUX) of CC2650. As far as I understand, I need to use Sensor Controller Studio (SCS) to do this. Then I need to write Contiki app for main CPU. And this two programs can interact via semaphores and AUX RAM.