diff --git a/cores/arduino/CDCSerialClass.cpp b/cores/arduino/CDCSerialClass.cpp index 878cbac6..c059cea8 100644 --- a/cores/arduino/CDCSerialClass.cpp +++ b/cores/arduino/CDCSerialClass.cpp @@ -30,12 +30,35 @@ #include "wiring_digital.h" #include "variant.h" -#define CDCACM_FIXED_DELAY 64 +#define CDC_MAILBOX_TX_CHANNEL 7 +#define CDC_MAILBOX_RX_CHANNEL 6 extern void CDCSerial_Handler(void); extern void serialEventRun1(void) __attribute__((weak)); extern void serialEvent1(void) __attribute__((weak)); +static void cdc_mbox_isr(CurieMailboxMsg msg) +{ + char *rxbuffptr = (char*)msg.data; + int new_head; + for(int i = 0; i < MBOX_BYTES; i++) + { + if((uint8_t)(*(rxbuffptr+i)) != '\0') + { + new_head = (Serial._rx_buffer->head +1) % CDCACM_BUFFER_SIZE; + if(new_head != Serial._rx_buffer->tail) + { + Serial._rx_buffer->data[Serial._rx_buffer->head] = *(rxbuffptr+i); + Serial._rx_buffer->head = new_head; + } + } + else + { + break; + } + } +} + // Constructors //////////////////////////////////////////////////////////////// CDCSerialClass::CDCSerialClass(uart_init_info *info) @@ -47,9 +70,9 @@ CDCSerialClass::CDCSerialClass(uart_init_info *info) void CDCSerialClass::setSharedData(struct cdc_acm_shared_data *cdc_acm_shared_data) { - this->_shared_data = cdc_acm_shared_data; - this->_rx_buffer = cdc_acm_shared_data->rx_buffer; - this->_tx_buffer = cdc_acm_shared_data->tx_buffer; + _shared_data = cdc_acm_shared_data; + _rx_buffer = cdc_acm_shared_data->rx_buffer; + _tx_buffer = cdc_acm_shared_data->tx_buffer; } void CDCSerialClass::begin(const uint32_t dwBaudRate) @@ -63,8 +86,13 @@ void CDCSerialClass::begin(const uint32_t dwBaudRate, const uint8_t config) } -void CDCSerialClass::init(const uint32_t dwBaudRate, const uint8_t modeReg) +void CDCSerialClass::init(uint32_t dwBaudRate, const uint8_t modeReg) { + /* Set a max internal baud rate due to the limitation of the + * Inter Processor Mailbox */ + if(dwBaudRate > 115200) + dwBaudRate = 115200; + /* Set a per-byte write delay approximately equal to the time it would * take to clock out a byte on a standard UART at this baud rate */ _writeDelayUsec = 8000000 / dwBaudRate; @@ -73,7 +101,9 @@ void CDCSerialClass::init(const uint32_t dwBaudRate, const uint8_t modeReg) * Empty the Rx buffer but don't touch Tx buffer: it is drained by the * LMT one way or another */ _rx_buffer->tail = _rx_buffer->head; - + + mailbox_register(CDC_MAILBOX_RX_CHANNEL, cdc_mbox_isr); + mailbox_enable_receive(CDC_MAILBOX_RX_CHANNEL); _shared_data->device_open = true; } @@ -84,12 +114,10 @@ void CDCSerialClass::end( void ) int CDCSerialClass::available( void ) { -#define SBS CDCACM_BUFFER_SIZE - if (!_shared_data->device_open) return (0); else - return (int)(SBS + _rx_buffer->head - _rx_buffer->tail) % SBS; + return (int)(CDCACM_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % CDCACM_BUFFER_SIZE; } int CDCSerialClass::availableForWrite(void) @@ -131,28 +159,61 @@ void CDCSerialClass::flush( void ) } } -size_t CDCSerialClass::write( const uint8_t uc_data ) +size_t CDCSerialClass::write(uint8_t uc_data ) { - uint32_t retries = 2; + CurieMailboxMsg cdcacm_msg; if (!_shared_data->device_open || !_shared_data->host_open) return(0); - do { - int i = (uint32_t)(_tx_buffer->head + 1) % CDCACM_BUFFER_SIZE; - // if we should be storing the received character into the location - // just before the tail (meaning that the head would advance to the - // current location of the tail), we're about to overflow the buffer - // and so we don't write the character or advance the head. - if (i != _tx_buffer->tail) { - _tx_buffer->data[_tx_buffer->head] = uc_data; - _tx_buffer->head = i; - - // Just use a fixed delay to make it compatible with the CODK-M based firmware - delayMicroseconds(CDCACM_FIXED_DELAY); - break; + cdcacm_msg.channel = CDC_MAILBOX_TX_CHANNEL; + cdcacm_msg.data[0] = uc_data; + mailbox_write(cdcacm_msg); + delayMicroseconds(_writeDelayUsec); + return 1; +} + +size_t CDCSerialClass::write(const uint8_t *buffer, size_t size) +{ + CurieMailboxMsg cdcacm_msg; + cdcacm_msg.channel = CDC_MAILBOX_TX_CHANNEL; + if (!_shared_data->device_open || !_shared_data->host_open) + return(0); + + int msg_len = size; + + for(int i = 0;msg_len > 0; msg_len -= MBOX_BYTES, i += MBOX_BYTES) + { + /* Copy data into mailbox message */ + memset(cdcacm_msg.data, 0, MBOX_BYTES); + if(msg_len >= MBOX_BYTES) + { + memcpy(cdcacm_msg.data, buffer+i, MBOX_BYTES); } - } while (retries--); + else + { + memcpy(cdcacm_msg.data, buffer+i, msg_len); + } + /* Write to mailbox*/ + mailbox_write(cdcacm_msg); + } - return 1; + // Mimick the throughput of a typical UART by throttling the data + // flow according to the configured baud rate + delayMicroseconds(_writeDelayUsec * size); + + return size; +} + +size_t CDCSerialClass::write(const char *str) +{ + if (str == NULL) return 0; + CurieMailboxMsg cdcacm_msg; + cdcacm_msg.channel = CDC_MAILBOX_TX_CHANNEL; + if (!_shared_data->device_open || !_shared_data->host_open) + return(0); + + int msg_len = strlen(str); + + return write((const uint8_t *)str, msg_len); } diff --git a/cores/arduino/CDCSerialClass.h b/cores/arduino/CDCSerialClass.h index f240ac38..74eb7b3b 100644 --- a/cores/arduino/CDCSerialClass.h +++ b/cores/arduino/CDCSerialClass.h @@ -26,6 +26,7 @@ #include "HardwareSerial.h" #include "platform.h" #include "wiring.h" +#include "mailbox.h" #include #include @@ -36,6 +37,10 @@ class CDCSerialClass : public HardwareSerial CDCSerialClass(uart_init_info *info); void setSharedData(struct cdc_acm_shared_data *cdc_acm_shared_data); + + struct cdc_acm_shared_data *_shared_data; + struct cdc_ring_buffer *_rx_buffer; + struct cdc_ring_buffer *_tx_buffer; void begin(const uint32_t dwBaudRate); void begin(const uint32_t dwBaudRate, const uint8_t config); @@ -46,6 +51,8 @@ class CDCSerialClass : public HardwareSerial int read(void); void flush(void); size_t write(const uint8_t c); + size_t write(const char *str); + size_t write(const uint8_t *buffer, size_t size); using Print::write; // pull in write(str) and write(buf, size) from Print operator bool() { @@ -56,11 +63,7 @@ class CDCSerialClass : public HardwareSerial }; protected: - void init(const uint32_t dwBaudRate, const uint8_t config); - - struct cdc_acm_shared_data *_shared_data; - struct cdc_ring_buffer *_rx_buffer; - struct cdc_ring_buffer *_tx_buffer; + void init(uint32_t dwBaudRate, const uint8_t config); uart_init_info *info; uint32_t _writeDelayUsec; diff --git a/cores/arduino/Print.h b/cores/arduino/Print.h index 16552079..96bd3022 100644 --- a/cores/arduino/Print.h +++ b/cores/arduino/Print.h @@ -47,7 +47,7 @@ class Print void clearWriteError() { setWriteError(0); } virtual size_t write(uint8_t) = 0; - size_t write(const char *str) { + virtual size_t write(const char *str) { if (str == NULL) return 0; return write((const uint8_t *)str, strlen(str)); } diff --git a/cores/arduino/Udp.h b/cores/arduino/Udp.h index dc5644b9..89f31c67 100644 --- a/cores/arduino/Udp.h +++ b/cores/arduino/Udp.h @@ -41,7 +41,8 @@ class UDP : public Stream { public: - virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual uint8_t begin(uint16_t) =0; // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use + virtual uint8_t beginMulticast(IPAddress, uint16_t) { return 0; } // initialize, start listening on specified multicast IP address and port. Returns 1 if successful, 0 on failure virtual void stop() =0; // Finish with the UDP socket // Sending UDP packets diff --git a/cores/arduino/mailbox.cpp b/cores/arduino/mailbox.cpp new file mode 100644 index 00000000..f8b54786 --- /dev/null +++ b/cores/arduino/mailbox.cpp @@ -0,0 +1,163 @@ +#include +#include "interrupt.h" +#include "scss_registers.h" +#include "mailbox.h" + +#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) + +/* Mailbox channel status register */ +#define IO_REG_MAILBOX_CHALL_STS (SCSS_REGISTER_BASE + 0xAC0) + +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; +static void (*callbacks[NUM_MAILBOX_CHANNELS])(CurieMailboxMsg); + +void mailbox_register (int channel, void(*callback)(CurieMailboxMsg)) +{ + if (channel >= 0 && channel < NUM_MAILBOX_CHANNELS) { + callbacks[channel] = callback; + } +} + +void mailbox_unregister (int channel) +{ + if (channel >= 0 && channel < NUM_MAILBOX_CHANNELS) { + callbacks[channel] = 0; + } +} + +void mailbox_disable_receive (int channel) +{ + intmask->ss_intmask |= 1 << channel; +} + +void mailbox_enable_receive (int channel) +{ + intmask->ss_intmask &= ~(1 << channel); +} + +static void do_callback (int channel, CurieMailboxMsg& msg) +{ + void (*cb)(CurieMailboxMsg) = callbacks[channel]; + if (cb) { + cb(msg); + } +} + +static void mailbox_read (int channel, CurieMailboxMsg& msg) +{ + unsigned int i; + + /* 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]; + } + + /* Clear channel status & interrupt flags */ + mbox[channel].sts |= CHANNEL_STS_BITS; +} + +void mailbox_write (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 uint16_t get_chall_sts (void) +{ + return MMIO_REG_VAL(IO_REG_MAILBOX_CHALL_STS) & CHALL_STATUS_MASK; +} + +static void mailbox_isr (void) +{ + int i; + uint32_t sts; + CurieMailboxMsg msg; + + sts = get_chall_sts(); + /* Get channel number */ + for (i = 0; i < NUM_MAILBOX_CHANNELS; ++i) { + if (sts & (1 << (i * 2 + 1))) { + break; + } + } + + mailbox_read(i, msg); + do_callback(i, msg); +} + +static void mailbox_hardware_init (void) +{ + int i; + + for (i = 0; i < NUM_MAILBOX_CHANNELS; ++i) { + mbox[i].sts &= ~(CHANNEL_STS_BITS); + } +} + +static void mailbox_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) mailbox_hardware_init(); + interrupt_connect(SOC_MBOX_INTERRUPT, mailbox_isr); + interrupt_enable(SOC_MBOX_INTERRUPT); +} + +void mailbox_init (bool master) +{ + intmask = (mbox_intmask_t *)IO_REG_MAILBOX_INT_MASK; + mbox = (mbox_channel_t *)IO_REG_MAILBOX_BASE; + memset(callbacks, 0, sizeof(callbacks)); + mailbox_interrupts_init(master); +} diff --git a/cores/arduino/mailbox.h b/cores/arduino/mailbox.h new file mode 100644 index 00000000..a72634eb --- /dev/null +++ b/cores/arduino/mailbox.h @@ -0,0 +1,22 @@ +#ifndef _MAILBOX_H_ +#define _MAILBOX_H_ + +#define NUM_MAILBOX_CHANNELS 8 +#define CHANNEL_DATA_WORDS 4 +#define MBOX_BYTES 16 + +class CurieMailboxMsg { +public: + uint32_t data[CHANNEL_DATA_WORDS]; + uint32_t id; + int channel = 0; +}; + +void mailbox_init (bool master); +void mailbox_register (int channel, void(*callback)(CurieMailboxMsg)); +void mailbox_unregister (int channel); +void mailbox_enable_receive (int channel); +void mailbox_disable_receive (int channel); +void mailbox_write(CurieMailboxMsg& msg); + +#endif diff --git a/cores/arduino/stdlib_noniso.cpp b/cores/arduino/stdlib_noniso.cpp index 14318e85..5215a041 100644 --- a/cores/arduino/stdlib_noniso.cpp +++ b/cores/arduino/stdlib_noniso.cpp @@ -199,6 +199,16 @@ char *dtostrf(double number, signed char width, unsigned char prec, char *s) return s; } + // rounding up to the precision + rounding = 0.5; + for (i = 0; i < prec; ++i) + rounding /= 10.0; + + if (number < 0.0) + number -= rounding; + else + number += rounding; + out = s; before = digitsBe4Decimal(number); @@ -215,12 +225,6 @@ char *dtostrf(double number, signed char width, unsigned char prec, char *s) number = -number; } - // rounding up to the precision - rounding = 0.5; - for (i = 0; i < prec; ++i) - rounding /= 10.0; - number += rounding; - // seperate integral and fractional parts integer = (unsigned long long) number; fraction = (double) (number - integer); @@ -235,17 +239,17 @@ char *dtostrf(double number, signed char width, unsigned char prec, char *s) out[i - 1] = ASCII_ZERO + integer; out += before; - if (!prec) goto end; - - // generate chars for each digit of the fractional part - *out++ = '.'; - for (i = 0; i < prec; ++i) { - fraction *= 10.0; - digit = ((unsigned long long) fraction) % 10; - *out++ = (char) (ASCII_ZERO + digit); + + if (prec) { + // generate chars for each digit of the fractional part + *out++ = '.'; + for (i = 0; i < prec; ++i) { + fraction *= 10.0; + digit = ((unsigned long long) fraction) % 10; + *out++ = (char) (ASCII_ZERO + digit); + } } -end: // check if padding is required if (width > 0) { delta = width - (before + prec + 1); diff --git a/drivers/amd64/WdfCoInstaller01009.dll b/drivers/amd64/WdfCoInstaller01009.dll new file mode 100644 index 00000000..1731b962 Binary files /dev/null and b/drivers/amd64/WdfCoInstaller01009.dll differ diff --git a/drivers/amd64/winusbcoinstaller2.dll b/drivers/amd64/winusbcoinstaller2.dll new file mode 100644 index 00000000..30e55025 Binary files /dev/null and b/drivers/amd64/winusbcoinstaller2.dll differ diff --git a/drivers/dpinst-amd64.exe b/drivers/dpinst-amd64.exe new file mode 100644 index 00000000..0507e738 Binary files /dev/null and b/drivers/dpinst-amd64.exe differ diff --git a/drivers/dpinst-x86.exe b/drivers/dpinst-x86.exe new file mode 100644 index 00000000..41a890d1 Binary files /dev/null and b/drivers/dpinst-x86.exe differ diff --git a/drivers/intc_composite.cat b/drivers/intc_composite.cat new file mode 100644 index 00000000..7c55789c Binary files /dev/null and b/drivers/intc_composite.cat differ diff --git a/drivers/intc_composite.inf b/drivers/intc_composite.inf new file mode 100644 index 00000000..2dc466b2 --- /dev/null +++ b/drivers/intc_composite.inf @@ -0,0 +1,46 @@ +;********************************************************************************************* +; Windows USB Composite Setup File for Arduino 101 +; +; Copyright (c) 2015 Intel Corporation +; +; For use only on Windows operating systems. +;********************************************************************************************* +[Version] +Signature = "$WINDOWS NT$" +Class = USB +ClassGUID = {4D36E978-E325-11CE-BFC1-08002BE10318} +Provider = %ProviderName% +DriverVer = 10/13/2015,1.1.0.0 +CatalogFile = intc_composite.cat + +[Manufacturer] +%ProviderName% = Generic,NTx86,NTamd64 + +[Generic.NTx86] +; Arduino 101 +%USBCompositeDevice% = Composite.Device,USB\VID_8087&PID_0AB6 ; ACM+ACM + +[Generic.NTamd64] +; Arduino 101 +%USBCompositeDevice% = Composite.Device,USB\VID_8087&PID_0AB6 ; ACM+ACM + +[ControlFlags] +ExcludeFromSelect=* + +; Common Class Generic Parent for root ID +[Composite.Device] +Include=usb.inf +Needs=Composite.Dev.NT + +[Composite.Device.Services] +Include=usb.inf +Needs=Composite.Dev.NT.Services + +[SourceDisksNames] +1=%SourceDisk%,,1 + +[Strings] +ProviderName = "Intel Corporation" +ServiceDisplayName = "Arduino 101 USB Composite Device Driver" +USBCompositeDevice = "Arduino 101 USB Composite Device" +SourceDisk = "Arduino 101 USB Composite Device Install Disk" diff --git a/drivers/intc_libusb.cat b/drivers/intc_libusb.cat new file mode 100644 index 00000000..ea90e2ca Binary files /dev/null and b/drivers/intc_libusb.cat differ diff --git a/drivers/intc_libusb.inf b/drivers/intc_libusb.inf new file mode 100644 index 00000000..cfc698d0 --- /dev/null +++ b/drivers/intc_libusb.inf @@ -0,0 +1,174 @@ +; ======== libusb 1.0 (WinUSB) device driver ========== +; +; To customize this inf file for your own device +; +; 1. Change "DeviceName" with the name you want your device to appear with +; on your system. +; +; 2. Change "VendorID" and "ProductID" according to those of your device. +; If your device is plugged in, you can retrieve these values through the +; Device Manager (regardless of whether the driver is installed or not). +; +; 3. Change "DeviceGUID" to a value that is unique on your system. For more +; information and tools to help you generate your own GUIDs, see +; http://en.wikipedia.org/wiki/Universally_Unique_Identifier. +; +; 4. Change "DeviceClassGUID" to reflect your USB Device Class. +; The following Device Classes are listed for reference: +; {745a17a0-74d3-11d0-b6fe-00a0c90f57da} : HID device +; {78a1c341-4539-11d3-b88d-00c04fad5171} : Generic WinUSB device +; +; 5. (Optional) Change the "Date" string. +; +; Note 1: if you need to create a matching cat file for this inf, you can use +; the inf2cat utility from the WinDDK, with the the following command: +; inf2cat /driver:"path_to_your inf" /os:7_X86,7_X64,Vista_X86,Vista_X64 +; +; Note 2: The co-installers provided in these files are version 1.9. +; Please refer to: +; http://blogs.msdn.com/iliast/archive/2008/03/10/why-do-we-need-wdf-coinstallers.aspx and +; http://blogs.msdn.com/iliast/archive/2009/08/13/wdf-logo-requirements-regarding-coinstallers.aspx +; for more information about co-installers and their versioning + +; ===================== Strings ======================= + +[Strings] + +; ===================================================== +; ========= START USER CONFIGURABLE SECTION =========== +; ===================================================== + +DeviceName = "Arduino 101 DFU Interface" +VendorID = "VID_8087" +ProductID = "PID_0ABA" +DeviceGUID = "{d35924d6-3e16-4a9e-9782-5524a4b79bac}" +DeviceClassGUID = "{78a1c341-4539-11d3-b88d-00c04fad5171}" +; Date MUST be in MM/DD/YYYY format +Date = "10/13/2015" + +; ===================================================== +; ========== END USER CONFIGURABLE SECTION ============ +; ===================================================== + +ProviderName = "libusb 1.0" +WinUSB_SvcDesc = "WinUSB Driver Service" +DiskName = "libusb (WinUSB) Device Install Disk" +ClassName = "libusb (WinUSB) devices" + +; ====================== Version ====================== + +[Version] +DriverVer = %Date% +Signature = "$Windows NT$" +Class = %ClassName% +ClassGuid = %DeviceClassGUID% +Provider = %ProviderName% +CatalogFile = intc_libusb.cat + +; =================== Class section =================== + +; Since the device is not a standard USB device, we define a new class for it. +[ClassInstall32] +Addreg = WinUSBDeviceClassReg + +[WinUSBDeviceClassReg] +HKR,,,0,%ClassName% +; -20 is for the USB icon +HKR,,Icon,,-20 + +; =========== Manufacturer/Models sections ============ + +[Manufacturer] +%ProviderName% = libusbDevice_WinUSB,NTx86,NTamd64 + +[libusbDevice_WinUSB.NTx86] +%DeviceName% = USB_Install, USB\%VendorID%&%ProductID% + +[libusbDevice_WinUSB.NTamd64] +%DeviceName% = USB_Install, USB\%VendorID%&%ProductID% + +; ==================== Installation =================== + +; The Include and Needs directives in the USB_Install section are required for +; installing WinUSB on Windows Vista systems. Windows XP systems ignore these +; directives. These directives should not be modified. +[USB_Install] +Include=winusb.inf +Needs=WINUSB.NT + +; The Include directive in the USB_Install.Services section includes the system- +; supplied INF for WinUSB. This INF is installed by the WinUSB co-installer if +; it is not already on the target system. The AddService directive specifies +; WinUsb.sys as the device’s function driver. These directives should not be +; modified. +[USB_Install.Services] +Include=winusb.inf +AddService=WinUSB,0x00000002,WinUSB_ServiceInstall + +; The WinUSB_ServiceInstall section contains the data for installing WinUsb.sys +; as a service. This section should not be modified. +[WinUSB_ServiceInstall] +DisplayName = %WinUSB_SvcDesc% +ServiceType = 1 +StartType = 3 +ErrorControl = 1 +ServiceBinary = %12%\WinUSB.sys + +; The KmdfService directive installs WinUsb.sys as a kernel-mode service. The +; referenced WinUSB_Install section specifies the KMDF library version. +; Usually, the version can be derived from the WdfCoInstallerxxyyy.dll with +; xx = major, yyy = minor +[USB_Install.Wdf] +KmdfService=WINUSB, WinUsb_Install + +[WinUSB_Install] +KmdfLibraryVersion=1.9 + +; USB_Install.HW is the key section in the INF. It specifies the device +; interface globally unique identifier (GUID) for your device. The AddReg +; directive puts the interface GUID in a standard registry value. When +; WinUsb.sys is loaded as the device’s function driver, it reads the registry +; value and uses the specified GUID to represent the device interface. You +; should replace the GUID in this example with one that you create specifically +; for your device. If the protocols for the device change, you should create a +; new device interface GUID. +[USB_Install.HW] +AddReg=Dev_AddReg + +[Dev_AddReg] +HKR,,DeviceInterfaceGUIDs,0x10000,%DeviceGUID% + +; The USB_Install.CoInstallers section, including the referenced AddReg and +; CopyFiles sections, contains data and instructions to install the WinUSB and +; KMDF co installers and associate them with the device. Most USB devices can +; use these sections and directives without modification. +[USB_Install.CoInstallers] +AddReg=CoInstallers_AddReg +CopyFiles=CoInstallers_CopyFiles + +[CoInstallers_AddReg] +HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01009.dll,WdfCoInstaller","WinUSBCoInstaller2.dll" + +[CoInstallers_CopyFiles] +WinUSBCoInstaller2.dll +WdfCoInstaller01009.dll + +[DestinationDirs] +CoInstallers_CopyFiles=11 + +; =============== Source Media Section ================ + +; The x86 and x64 versions of Windows have separate co installers. This example +; stores them on the installation disk in folders that are named x86 and amd64 +[SourceDisksNames] +1 = %DiskName%,,,\x86 +2 = %DiskName%,,,\amd64 + +[SourceDisksFiles.x86] +WinUSBCoInstaller2.dll=1 +WdfCoInstaller01009.dll=1 + +[SourceDisksFiles.amd64] +WinUSBCoInstaller2.dll=2 +WdfCoInstaller01009.dll=2 + diff --git a/drivers/intc_serial.cat b/drivers/intc_serial.cat new file mode 100644 index 00000000..ab02985d Binary files /dev/null and b/drivers/intc_serial.cat differ diff --git a/drivers/intc_serial.inf b/drivers/intc_serial.inf new file mode 100644 index 00000000..e3e7439a --- /dev/null +++ b/drivers/intc_serial.inf @@ -0,0 +1,73 @@ +;************************************************************ +; Windows USB CDC ACM Setup File +; Copyright (c) 2000 Microsoft Corporation + + +[Version] +Signature="$Windows NT$" +Class=Ports +ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318} +Provider=%MFGNAME% +DriverVer=10/13/2015,5.1.2600.0 +CatalogFile = intc_serial.cat + +[Manufacturer] +%MFGNAME%=DeviceList, NTamd64 + +[DestinationDirs] +DefaultDestDir=12 + + +;------------------------------------------------------------------------------ +; Vendor and Product ID Definitions +;------------------------------------------------------------------------------ +; When developing your USB device, the VID and PID used in the PC side +; application program and the firmware on the microcontroller must match. +; Modify the below line to use your VID and PID. Use the format as shown below. +; Note: One INF file can be used for multiple devices with different VID and PIDs. +; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line. +;------------------------------------------------------------------------------ + +[DeviceList] +%DESCRIPTION%=DriverInstall, USB\VID_8087&PID_0AB6 + +[DeviceList.NTamd64] +%DESCRIPTION%=DriverInstall, USB\VID_8087&PID_0AB6 + + + +;------------------------------------------------------------------------------ +; String Definitions +;------------------------------------------------------------------------------ +;Modify these strings to customize your device +;------------------------------------------------------------------------------ +[Strings] +MFGFILENAME="CDC_vista" +DRIVERFILENAME ="usbser" +MFGNAME="http://www.intel.com" +INSTDISK="Arduino 101 Driver Installer" +DESCRIPTION="Arduino 101 Serial Monitor" +SERVICE="USB RS-232 Emulation Driver" + + +[DriverInstall] +include=mdmcpq.inf,usb.inf +CopyFiles = FakeModemCopyFileSection +AddReg=DriverAddReg + +[DriverAddReg] +HKR,,DevLoader,,*ntkern +HKR,,NTMPDriver,,usbser.sys +HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider" + +[DriverInstall.Services] +include=mdmcpq.inf +AddService=usbser, 0x00000002, DriverService + +[DriverService] +DisplayName=%ServiceName% +ServiceType=1 +StartType=3 +ErrorControl=1 +ServiceBinary=%12%\usbser.sys +LoadOrderGroup=Base diff --git a/drivers/x86/WdfCoInstaller01009.dll b/drivers/x86/WdfCoInstaller01009.dll new file mode 100644 index 00000000..30e81af6 Binary files /dev/null and b/drivers/x86/WdfCoInstaller01009.dll differ diff --git a/drivers/x86/winusbcoinstaller2.dll b/drivers/x86/winusbcoinstaller2.dll new file mode 100644 index 00000000..fc450d2b Binary files /dev/null and b/drivers/x86/winusbcoinstaller2.dll differ diff --git a/libraries/CurieBLE/examples/central/led_control/led_control.ino b/libraries/CurieBLE/examples/Central/LedControl/LedControl.ino similarity index 99% rename from libraries/CurieBLE/examples/central/led_control/led_control.ino rename to libraries/CurieBLE/examples/Central/LedControl/LedControl.ino index 0ef64ff6..2c1706a1 100644 --- a/libraries/CurieBLE/examples/central/led_control/led_control.ino +++ b/libraries/CurieBLE/examples/Central/LedControl/LedControl.ino @@ -4,7 +4,7 @@ */ /* - * Sketch: led_control.ino + * Sketch: LedControl.ino * * Description: * This is a Central sketch that looks for a particular Sevice with a diff --git a/libraries/CurieBLE/examples/central/peripheral_explorer/peripheral_explorer.ino b/libraries/CurieBLE/examples/Central/PeripheralExplorer/PeripheralExplorer.ino similarity index 99% rename from libraries/CurieBLE/examples/central/peripheral_explorer/peripheral_explorer.ino rename to libraries/CurieBLE/examples/Central/PeripheralExplorer/PeripheralExplorer.ino index e9511f48..b89492b1 100644 --- a/libraries/CurieBLE/examples/central/peripheral_explorer/peripheral_explorer.ino +++ b/libraries/CurieBLE/examples/Central/PeripheralExplorer/PeripheralExplorer.ino @@ -4,7 +4,7 @@ */ /* - * Sketch: peripheral_explorer.ino + * Sketch:PeripheralExplorer.ino * * Description: * This is a Central sketch demonstrating the discovery process diff --git a/libraries/CurieBLE/examples/central/scan/scan.ino b/libraries/CurieBLE/examples/Central/Scan/Scan.ino similarity index 99% rename from libraries/CurieBLE/examples/central/scan/scan.ino rename to libraries/CurieBLE/examples/Central/Scan/Scan.ino index d191d033..6af4b49f 100644 --- a/libraries/CurieBLE/examples/central/scan/scan.ino +++ b/libraries/CurieBLE/examples/Central/Scan/Scan.ino @@ -4,7 +4,7 @@ */ /* - * Sketch: scan.ino + * Sketch: Scan.ino * * Description: * This is a Central sketch that performs scanning of Peripherals diff --git a/libraries/CurieBLE/examples/central/scan_callback/scan_callback.ino b/libraries/CurieBLE/examples/Central/ScanCallback/ScanCallback.ino similarity index 99% rename from libraries/CurieBLE/examples/central/scan_callback/scan_callback.ino rename to libraries/CurieBLE/examples/Central/ScanCallback/ScanCallback.ino index fe853cd6..4c47decd 100644 --- a/libraries/CurieBLE/examples/central/scan_callback/scan_callback.ino +++ b/libraries/CurieBLE/examples/Central/ScanCallback/ScanCallback.ino @@ -4,7 +4,7 @@ */ /* - * Sketch: scan_callback.ino + * Sketch: ScanCallback.ino * * Description: * This is a Central Sketch that scan for Peripherals without diff --git a/libraries/CurieBLE/examples/central/sensortag_button/sensortag_button.ino b/libraries/CurieBLE/examples/Central/SensortagButton/SensortagButton.ino similarity index 99% rename from libraries/CurieBLE/examples/central/sensortag_button/sensortag_button.ino rename to libraries/CurieBLE/examples/Central/SensortagButton/SensortagButton.ino index 3209012f..75de9267 100644 --- a/libraries/CurieBLE/examples/central/sensortag_button/sensortag_button.ino +++ b/libraries/CurieBLE/examples/Central/SensortagButton/SensortagButton.ino @@ -4,7 +4,7 @@ */ /* - * Sketch: sensortag_button.ino + * Sketch: SensortagButton.ino * * Description: * This Central sketch scan for a Peripheral called the SensorTag. diff --git a/libraries/CurieBLE/examples/peripheral/BatteryMonitor/BatteryMonitor.ino b/libraries/CurieBLE/examples/Peripheral/BatteryMonitor/BatteryMonitor.ino similarity index 100% rename from libraries/CurieBLE/examples/peripheral/BatteryMonitor/BatteryMonitor.ino rename to libraries/CurieBLE/examples/Peripheral/BatteryMonitor/BatteryMonitor.ino diff --git a/libraries/CurieBLE/examples/peripheral/ButtonLED/ButtonLED.ino b/libraries/CurieBLE/examples/Peripheral/ButtonLED/ButtonLED.ino similarity index 97% rename from libraries/CurieBLE/examples/peripheral/ButtonLED/ButtonLED.ino rename to libraries/CurieBLE/examples/Peripheral/ButtonLED/ButtonLED.ino index 72a88a5e..fb91c18e 100644 --- a/libraries/CurieBLE/examples/peripheral/ButtonLED/ButtonLED.ino +++ b/libraries/CurieBLE/examples/Peripheral/ButtonLED/ButtonLED.ino @@ -53,7 +53,7 @@ void loop() { char buttonValue = digitalRead(buttonPin); // has the value changed since the last read - boolean buttonChanged = (buttonCharacteristic.value() != buttonValue); + bool buttonChanged = (buttonCharacteristic.value() != buttonValue); if (buttonChanged) { // button state changed, update characteristics diff --git a/libraries/CurieBLE/examples/peripheral/CallbackLED/CallbackLED.ino b/libraries/CurieBLE/examples/Peripheral/CallbackLED/CallbackLED.ino similarity index 100% rename from libraries/CurieBLE/examples/peripheral/CallbackLED/CallbackLED.ino rename to libraries/CurieBLE/examples/Peripheral/CallbackLED/CallbackLED.ino diff --git a/libraries/CurieBLE/examples/peripheral/LED/LED.ino b/libraries/CurieBLE/examples/Peripheral/LED/LED.ino similarity index 100% rename from libraries/CurieBLE/examples/peripheral/LED/LED.ino rename to libraries/CurieBLE/examples/Peripheral/LED/LED.ino diff --git a/libraries/CurieBLE/examples/peripheral/MIDIBLE/MIDIBLE.ino b/libraries/CurieBLE/examples/Peripheral/MIDIBLE/MIDIBLE.ino similarity index 100% rename from libraries/CurieBLE/examples/peripheral/MIDIBLE/MIDIBLE.ino rename to libraries/CurieBLE/examples/Peripheral/MIDIBLE/MIDIBLE.ino diff --git a/libraries/CurieBLE/examples/test/BatteryMonitor_Central/BatteryMonitor_Central.ino b/libraries/CurieBLE/examples/test/BatteryMonitor_Central/BatteryMonitor_Central.ino deleted file mode 100644 index 90a39dfb..00000000 --- a/libraries/CurieBLE/examples/test/BatteryMonitor_Central/BatteryMonitor_Central.ino +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation. All rights reserved. - * See the bottom of this file for the license terms. - */ - -/* - * Sketch: BatteryMonitor_Central.ino - * - * Description: - * This sketch will receive the notifications and output the received - * data in the serial monitor. It also illustrates using a non-typed - * characteristic. - * - * Notes: - * - * - Set the baud rate to 115200 on the serial monitor to accomodate - * the speed of constant data updates - * - Expected Peripheral name: BatteryMonitorSketch - * - Expected Peripheral Characteristic: 2A19 - * - Expected Peripheral sketch: BatteryMonitor_Notification.ino - * - */ - -#include - -#define LED_PIN 13 - - -void setup() -{ - // This is set to higher baud rate because accelerometer data changes very quickly - Serial.begin(9600); // initialize serial communication - while (!Serial); - pinMode(LED_PIN, OUTPUT); // initialize the LED on pin 13 to indicate when a central is connected - - /* Now activate the BLE device. It will start continuously transmitting BLE - advertising packets and will be visible to remote BLE central devices - until it receives a new connection */ - BLE.begin(); - Serial.print("My Address is: "); - Serial.println(BLE.address()); - - BLE.scanForName("BatteryMonitorSketch"); - Serial.println("Scan Started"); -} - - -void loop() -{ - BLEDevice peripheral = BLE.available(); - - if (peripheral) - { - Serial.print("Found "); - Serial.print(peripheral.address()); - Serial.print(" '"); - Serial.print(peripheral.localName()); - Serial.print("' "); - Serial.print(peripheral.advertisedServiceUuid()); - Serial.println(); - if ( peripheral.localName() == "BatteryMonitorSketch") { - BLE.stopScan(); - processNotification(peripheral); - - delay (1000); - } - - // central connected to peripheral - - //delay (4000); - // BLE.scan();//("BatteryMonitorSketch"); - } -} - -void processNotification(BLEDevice peripheral) { - if (peripheral.connect()) { - Serial.print("Connected: "); - Serial.println(peripheral.address()); - // light pin to indicate connection - digitalWrite(LED_PIN, HIGH); - } else { - Serial.println("Failed to connect!"); - return; - } - - // discover peripheral attributes - Serial.println("Discovering attributes ..."); - if (peripheral.discoverAttributes()) { - Serial.println("Attributes discovered"); - } else { - Serial.println("Attribute discovery failed!"); - peripheral.disconnect(); - digitalWrite(LED_PIN, LOW); - return; - } - BLECharacteristic batteryLevelChar = peripheral.characteristic("2A19"); - if (!batteryLevelChar) { - peripheral.disconnect(); - Serial.println("Peripheral does not have battery level characteristic!"); - digitalWrite(LED_PIN, LOW); - delay(1000); - return; - } - - if (!batteryLevelChar.subscribe()) { - Serial.println("subscription failed!"); - peripheral.disconnect(); - return; - } else { - Serial.println("Subscribed"); - } - - while (peripheral.connected()) - { - if (batteryLevelChar.valueUpdated()) { - - printData(batteryLevelChar.value(), batteryLevelChar.valueLength()); - Serial.println("%"); - - } - - } - Serial.print("Disconnected"); - Serial.println(peripheral.address()); - digitalWrite(LED_PIN, LOW); -} - - -void printData(const unsigned char data[], int length) { - for (int i = 0; i < length; i++) { - unsigned char b = data[i]; - - if (b < 16) { - Serial.print("0"); - } - - Serial.print(b); - } -} - -/* - 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/CurieBLE/examples/test/CallbackLED/CallbackLED.ino b/libraries/CurieBLE/examples/test/CallbackLED/CallbackLED.ino deleted file mode 100644 index 7cbcd21b..00000000 --- a/libraries/CurieBLE/examples/test/CallbackLED/CallbackLED.ino +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation. All rights reserved. - * See the bottom of this file for the license terms. - */ - -#include "CurieBLE.h" - -const int ledPin = 13; // set ledPin to use on-board LED -BLEPeripheral blePeripheral; // create peripheral instance - -BLEService ledService("19B10000-E8F2-537E-4F6C-D104768A1214"); // create service - -// create switch characteristic and allow remote device to read and write -BLECharCharacteristic switchChar("19B10001-E8F2-537E-4F6C-D104768A1214", BLERead | BLEWrite); - -void setup() { - Serial.begin(9600); - pinMode(ledPin, OUTPUT); // use the LED on pin 13 as an output - - // set the local name peripheral advertises - blePeripheral.setLocalName("LEDCB"); - // set the UUID for the service this peripheral advertises - blePeripheral.setAdvertisedServiceUuid(ledService.uuid()); - - // add service and characteristic - blePeripheral.addAttribute(ledService); - blePeripheral.addAttribute(switchChar); - - // assign event handlers for connected, disconnected to peripheral - blePeripheral.setEventHandler(BLEConnected, blePeripheralConnectHandler); - blePeripheral.setEventHandler(BLEDisconnected, blePeripheralDisconnectHandler); - - // assign event handlers for characteristic - switchChar.setEventHandler(BLEWritten, switchCharacteristicWritten); -// set an initial value for the characteristic - switchChar.setValue(0); - - // advertise the service - blePeripheral.begin(); - Serial.println(("Bluetooth device active, waiting for connections...")); -} - -void loop() { - // poll peripheral - blePeripheral.poll(); -} - -void blePeripheralConnectHandler(BLECentral& central) { - // central connected event handler - Serial.print("Connected event, central: "); - Serial.println(central.address()); -} - -void blePeripheralDisconnectHandler(BLECentral& central) { - // central disconnected event handler - Serial.print("Disconnected event, central: "); - Serial.println(central.address()); -} - -void switchCharacteristicWritten(BLEDevice central, BLECharacteristic characteristic) { - // central wrote new value to characteristic, update LED - Serial.print("Characteristic event, written: "); - - if (switchChar.value()) { - Serial.println("LED on"); - digitalWrite(ledPin, HIGH); - } else { - Serial.println("LED off"); - digitalWrite(ledPin, LOW); - } -} - -/* - 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/CurieBLE/examples/test/CentralDouble/CentralDouble.ino b/libraries/CurieBLE/examples/test/CentralDouble/CentralDouble.ino deleted file mode 100644 index 45089df4..00000000 --- a/libraries/CurieBLE/examples/test/CentralDouble/CentralDouble.ino +++ /dev/null @@ -1,126 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation. All rights reserved. - * See the bottom of this file for the license terms. - */ - -/* - * Sketch: CentralDouble.ino. - * - * Description: - * This is a simple BLE sketch that initiates the - * Arduino platform as a Central. It reads a double value from - * a connected Peripheral. The sketch exercises: Scanning for - * a specific Peripheral, connecting to it, discover its Attributes, - * and exercise a specific Characteristic to read a double value - * from the Peripheral. - * - * Notes: - * Expected Peripheral name: DataTest - * Expected Peripheral Characteristic: 19b20001e8f2537e4f6cd104768a1214 - * Expected Characteristic read value: double. - */ - -#include "CurieBLE.h" - - -// LED pin -#define LED_PIN 13 - -void setup() { - Serial.begin(9600); - - // set LED pin to output mode - pinMode(LED_PIN, OUTPUT); - - // begin initialization - BLE.begin(); - Serial.println(BLE.address()); - - BLE.scanForName("DataTest"); -} - -void loop() { - BLEDevice peripheral = BLE.available(); - if (peripheral) - { - Serial.println(peripheral.address()); - BLE.stopScan(); - // central connected to peripheral - controlLogic(peripheral); - BLE.scanForName("DataTest"); - } -} - - -void controlLogic(BLEDevice &peripheral) -{ - // connect to the peripheral - Serial.print("Connecting ... "); - Serial.println(peripheral.address()); - - if (peripheral.connect()) - { - Serial.print("Connected: "); - Serial.println(peripheral.address()); - } - else - { - Serial.println("Failed to connect!"); - return; - } - - if (peripheral.discoverAttributes() == false) - { - Serial.println("Discover failed, Disconnecting..."); - peripheral.disconnect(); - return; - } - - BLECharacteristic doubleCharacteristic = peripheral.characteristic("19b20001e8f2537e4f6cd104768a1214"); - - if (!doubleCharacteristic) - { - peripheral.disconnect(); - Serial.println("Peripheral does not have test double characteristic!"); - delay(5000); - return; - } - doubleCharacteristic.subscribe(); - - while (peripheral.connected()) - { - doubleCharacteristic.read(); - delay(1000); - if (doubleCharacteristic.valueUpdated()) - { - Serial.print("Double characteristic value: "); - Serial.println(doubleCharacteristic.doubleValue()); - } - delay(1000); - } - Serial.print("Disconnected"); - Serial.println(peripheral.address()); -} - - - -/* - Arduino BLE Peripheral Double read/write test example - Copyright (c) 2016 Arduino LLC. All right 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 St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - diff --git a/libraries/CurieBLE/examples/test/CommunitySketches/Genuino101CurieBLEHeartRateMonitor/Genuino101CurieBLEHeartRateMonitor.ino b/libraries/CurieBLE/examples/test/CommunitySketches/Genuino101CurieBLEHeartRateMonitor/Genuino101CurieBLEHeartRateMonitor.ino deleted file mode 100644 index 5428572f..00000000 --- a/libraries/CurieBLE/examples/test/CommunitySketches/Genuino101CurieBLEHeartRateMonitor/Genuino101CurieBLEHeartRateMonitor.ino +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation. All rights reserved. - * See the bottom of this file for the license terms. - */ - -/* - * Sketch: Genuino101CurieBLEHeartRateMonitor.ino. - * - * Description: - * This sketch example partially implements the standard Bluetooth Low-Energy - * Heart Rate service. For more information: - * https://developer.bluetooth.org/gatt/services/Pages/ServicesHome.aspx - * - */ - -#include - -BLEPeripheral blePeripheral; // BLE Peripheral Device (the board you're programming) -BLEService heartRateService("180D"); // BLE Heart Rate Service - -// BLE Heart Rate Measurement Characteristic" -BLECharacteristic heartRateChar("2A37", // standard 16-bit characteristic UUID - BLERead | BLENotify, 2); // remote clients will be able to get notifications if this characteristic changes - // the characteristic is 2 bytes long as the first field needs to be "Flags" as per BLE specifications - // https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml - -int oldHeartRate = 0; // last heart rate reading from analog input -long previousMillis = 0; // last time the heart rate was checked, in ms - -void setup() { - Serial.begin(9600); // initialize serial communication - pinMode(13, OUTPUT); // initialize the LED on pin 13 to indicate when a central is connected - - /* Set a local name for the BLE device - This name will appear in advertising packets - and can be used by remote devices to identify this BLE device - The name can be changed but maybe be truncated based on space left in advertisement packet */ - blePeripheral.setLocalName("HeartRateSketch"); - blePeripheral.setAdvertisedServiceUuid(heartRateService.uuid()); // add the service UUID - blePeripheral.addAttribute(heartRateService); // Add the BLE Heart Rate service - blePeripheral.addAttribute(heartRateChar); // add the Heart Rate Measurement characteristic - - /* Now activate the BLE device. It will start continuously transmitting BLE - advertising packets and will be visible to remote BLE central devices - until it receives a new connection */ - blePeripheral.begin(); - Serial.println("Bluetooth device active, waiting for connections..."); -} - -void loop() { - // listen for BLE peripherals to connect: - BLECentral central = blePeripheral.central(); - - // if a central is connected to peripheral: - if (central) { - Serial.print("Connected to central: "); - // print the central's MAC address: - Serial.println(central.address()); - // turn on the LED to indicate the connection: - digitalWrite(13, HIGH); - - // check the heart rate measurement every 200ms - // as long as the central is still connected: - while (central.connected()) { - long currentMillis = millis(); - // if 200ms have passed, check the heart rate measurement: - if (currentMillis - previousMillis >= 200) { - previousMillis = currentMillis; - updateHeartRate(); - } - } - // when the central disconnects, turn off the LED: - digitalWrite(13, LOW); - Serial.print("Disconnected from central: "); - Serial.println(central.address()); - } -} - -void updateHeartRate() { - /* Read the current voltage level on the A0 analog input pin. - This is used here to simulate the heart rate's measurement. - */ - int heartRateMeasurement = analogRead(A0); - int heartRate = map(heartRateMeasurement, 0, 1023, 0, 100); - if (heartRate != oldHeartRate) { // if the heart rate has changed - Serial.print("Heart Rate is now: "); // print it - Serial.println(heartRate); - const unsigned char heartRateCharArray[2] = { 0, (char)heartRate }; - heartRateChar.setValue(heartRateCharArray, 2); // and update the heart rate measurement characteristic - oldHeartRate = heartRate; // save the level for next comparison - } -} - -/* - Copyright (c) 2015 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/CurieBLE/examples/test/CommunitySketches/StandardFirmataBLE/BLEStream.h b/libraries/CurieBLE/examples/test/CommunitySketches/StandardFirmataBLE/BLEStream.h deleted file mode 100644 index 87256762..00000000 --- a/libraries/CurieBLE/examples/test/CommunitySketches/StandardFirmataBLE/BLEStream.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - BLEStream.h - - Based on BLESerial.cpp by Voita Molda - https://github.com/sandeepmistry/arduino-BLEPeripheral/blob/master/examples/serial/BLESerial.h - - Last updated April 4th, 2016 - */ - -#ifndef _BLE_STREAM_H_ -#define _BLE_STREAM_H_ - -#include -#if defined(_VARIANT_ARDUINO_101_X_) -#include -#define _MAX_ATTR_DATA_LEN_ BLE_MAX_ATTR_DATA_LEN -#else -//#include -#define _MAX_ATTR_DATA_LEN_ BLE_ATTRIBUTE_MAX_VALUE_LENGTH -#endif - -#define BLESTREAM_TXBUFFER_FLUSH_INTERVAL 80 -#define BLESTREAM_MIN_FLUSH_INTERVAL 8 // minimum interval for flushing the TX buffer - -// #define BLE_SERIAL_DEBUG - -class BLEStream : public BLEPeripheral, public Stream -{ - public: - BLEStream(unsigned char req = 0, unsigned char rdy = 0, unsigned char rst = 0); - - void begin(...); - bool poll(); - void end(); - void setFlushInterval(int); - - virtual int available(void); - virtual int peek(void); - virtual int read(void); - virtual void flush(void); - virtual size_t write(uint8_t byte); - using Print::write; - virtual operator bool(); - - private: - bool _connected; - unsigned long _flushed; - int _flushInterval; - static BLEStream* _instance; - - size_t _rxHead; - size_t _rxTail; - size_t _rxCount() const; - unsigned char _rxBuffer[256]; - size_t _txCount; - unsigned char _txBuffer[_MAX_ATTR_DATA_LEN_]; - - BLEService _uartService = BLEService("6E400001-B5A3-F393-E0A9-E50E24DCCA9E"); - BLEDescriptor _uartNameDescriptor = BLEDescriptor("2901", "UART"); - BLECharacteristic _rxCharacteristic = BLECharacteristic("6E400002-B5A3-F393-E0A9-E50E24DCCA9E", BLEWriteWithoutResponse, _MAX_ATTR_DATA_LEN_); - BLEDescriptor _rxNameDescriptor = BLEDescriptor("2901", "RX - Receive Data (Write)"); - BLECharacteristic _txCharacteristic = BLECharacteristic("6E400003-B5A3-F393-E0A9-E50E24DCCA9E", BLENotify, _MAX_ATTR_DATA_LEN_); - BLEDescriptor _txNameDescriptor = BLEDescriptor("2901", "TX - Transfer Data (Notify)"); - - void _received(const unsigned char* data, size_t size); - static void _received(BLECentral& /*central*/, BLECharacteristic& rxCharacteristic); -}; - - -/* - * BLEStream.cpp - * Copied here as a hack to avoid having to install the BLEPeripheral libarary even if it's - * not needed. - */ - -BLEStream* BLEStream::_instance = NULL; - -BLEStream::BLEStream(unsigned char req, unsigned char rdy, unsigned char rst) : -#if defined(_VARIANT_ARDUINO_101_X_) - BLEPeripheral() -#else - BLEPeripheral(req, rdy, rst) -#endif -{ - this->_txCount = 0; - this->_rxHead = this->_rxTail = 0; - this->_flushed = 0; - this->_flushInterval = BLESTREAM_TXBUFFER_FLUSH_INTERVAL; - BLEStream::_instance = this; - - addAttribute(this->_uartService); - addAttribute(this->_uartNameDescriptor); - setAdvertisedServiceUuid(this->_uartService.uuid()); - addAttribute(this->_rxCharacteristic); - addAttribute(this->_rxNameDescriptor); - this->_rxCharacteristic.setEventHandler(BLEWritten, BLEStream::_received); - addAttribute(this->_txCharacteristic); - addAttribute(this->_txNameDescriptor); -} - -void BLEStream::begin(...) -{ - BLEPeripheral::begin(); -#ifdef BLE_SERIAL_DEBUG - Serial.println(F("BLEStream::begin()")); -#endif -} - -bool BLEStream::poll() -{ - // BLEPeripheral::poll is called each time connected() is called - this->_connected = BLEPeripheral::connected(); - if (millis() > this->_flushed + this->_flushInterval) { - flush(); - } - return this->_connected; -} - -void BLEStream::end() -{ - this->_rxCharacteristic.setEventHandler(BLEWritten, (void(*)(BLECentral&, BLECharacteristic&))NULL); - this->_rxHead = this->_rxTail = 0; - flush(); - BLEPeripheral::disconnect(); -} - -int BLEStream::available(void) -{ -// BLEPeripheral::poll only calls delay(1) in CurieBLE so skipping it here to avoid the delay -#ifndef _VARIANT_ARDUINO_101_X_ - // TODO Need to do more testing to determine if all of these calls to BLEPeripheral::poll are - // actually necessary. Seems to run fine without them, but only minimal testing so far. - BLEPeripheral::poll(); -#endif - int retval = (this->_rxHead - this->_rxTail + sizeof(this->_rxBuffer)) % sizeof(this->_rxBuffer); -#ifdef BLE_SERIAL_DEBUG - if (retval > 0) { - Serial.print(F("BLEStream::available() = ")); - Serial.println(retval); - } -#endif - return retval; -} - -int BLEStream::peek(void) -{ -#ifndef _VARIANT_ARDUINO_101_X_ - BLEPeripheral::poll(); -#endif - if (this->_rxTail == this->_rxHead) return -1; - uint8_t byte = this->_rxBuffer[this->_rxTail]; -#ifdef BLE_SERIAL_DEBUG - Serial.print(F("BLEStream::peek() = 0x")); - Serial.println(byte, HEX); -#endif - return byte; -} - -int BLEStream::read(void) -{ -#ifndef _VARIANT_ARDUINO_101_X_ - BLEPeripheral::poll(); -#endif - if (this->_rxTail == this->_rxHead) return -1; - this->_rxTail = (this->_rxTail + 1) % sizeof(this->_rxBuffer); - uint8_t byte = this->_rxBuffer[this->_rxTail]; -#ifdef BLE_SERIAL_DEBUG - Serial.print(F("BLEStream::read() = 0x")); - Serial.println(byte, HEX); -#endif - return byte; -} - -void BLEStream::flush(void) -{ - if (this->_txCount == 0) return; -#ifndef _VARIANT_ARDUINO_101_X_ - // ensure there are available packets before sending - while(!this->_txCharacteristic.canNotify()) { - BLEPeripheral::poll(); - } -#endif - this->_txCharacteristic.setValue(this->_txBuffer, this->_txCount); - this->_flushed = millis(); - this->_txCount = 0; -#ifdef BLE_SERIAL_DEBUG - Serial.println(F("BLEStream::flush()")); -#endif -} - -size_t BLEStream::write(uint8_t byte) -{ -#ifndef _VARIANT_ARDUINO_101_X_ - BLEPeripheral::poll(); -#endif - if (this->_txCharacteristic.subscribed() == false) return 0; - this->_txBuffer[this->_txCount++] = byte; - if (this->_txCount == sizeof(this->_txBuffer)) flush(); -#ifdef BLE_SERIAL_DEBUG - Serial.print(F("BLEStream::write( 0x")); - Serial.print(byte, HEX); - Serial.println(F(") = 1")); -#endif - return 1; -} - -BLEStream::operator bool() -{ - bool retval = this->_connected = BLEPeripheral::connected(); -#ifdef BLE_SERIAL_DEBUG - Serial.print(F("BLEStream::operator bool() = ")); - Serial.println(retval); -#endif - return retval; -} - -void BLEStream::setFlushInterval(int interval) -{ - if (interval > BLESTREAM_MIN_FLUSH_INTERVAL) { - this->_flushInterval = interval; - } -} - -void BLEStream::_received(const unsigned char* data, size_t size) -{ - for (size_t i = 0; i < size; i++) { - this->_rxHead = (this->_rxHead + 1) % sizeof(this->_rxBuffer); - this->_rxBuffer[this->_rxHead] = data[i]; - } -#ifdef BLE_SERIAL_DEBUG - Serial.print(F("BLEStream::received(")); - for (int i = 0; i < size; i++) Serial.print(data[i], HEX); - Serial.println(F(")")); -#endif -} - -void BLEStream::_received(BLECentral& /*central*/, BLECharacteristic& rxCharacteristic) -{ - BLEStream::_instance->_received(rxCharacteristic.value(), rxCharacteristic.valueLength()); -} - - -#endif // _BLE_STREAM_H_ diff --git a/libraries/CurieBLE/examples/test/CommunitySketches/StandardFirmataBLE/StandardFirmataBLE.ino b/libraries/CurieBLE/examples/test/CommunitySketches/StandardFirmataBLE/StandardFirmataBLE.ino deleted file mode 100644 index 398993f9..00000000 --- a/libraries/CurieBLE/examples/test/CommunitySketches/StandardFirmataBLE/StandardFirmataBLE.ino +++ /dev/null @@ -1,853 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation. All rights reserved. - * See the bottom of this file for the license terms. - */ - -/* - * Sketch: StandardFirmataBLE.ino. - * - * Description: - * Firmata is a generic protocol for communicating with microcontrollers - * from software on a host computer. It is intended to work with - * any host computer software package. - * - * Notes: - * - Please use the link stated at the end of this file to - * download a host s/w package. - */ - -#include -#include -#include - -//#define SERIAL_DEBUG -#include "utility/firmataDebug.h" - -/* - * Uncomment the following include to enable interfacing - * with Serial devices via hardware or software serial. - */ -// In order to use software serial, you will need to compile this sketch with -// Arduino IDE v1.6.6 or higher. Hardware serial should work back to Arduino 1.0. -//#include "utility/SerialFirmata.h" - -// follow the instructions in bleConfig.h to configure your BLE hardware -#include "bleConfig.h" - -#define I2C_WRITE 0x00 //B00000000 -#define I2C_READ 0x08 //B00001000 -#define I2C_READ_CONTINUOUSLY 0x10 //B00010000 -#define I2C_STOP_READING 0x18 //B00011000 -#define I2C_READ_WRITE_MODE_MASK 0x18 //B00011000 -#define I2C_10BIT_ADDRESS_MODE_MASK 0x20 //B00100000 -#define I2C_END_TX_MASK 0x40 //B01000000 -#define I2C_STOP_TX 1 -#define I2C_RESTART_TX 0 -#define I2C_MAX_QUERIES 8 -#define I2C_REGISTER_NOT_SPECIFIED -1 - -// the minimum interval for sampling analog input -#define MINIMUM_SAMPLING_INTERVAL 1 - -// min cannot be < 0x0006. Adjust max if necessary -#define FIRMATA_BLE_MIN_INTERVAL 0x0006 // 7.5ms (7.5 / 1.25) -#define FIRMATA_BLE_MAX_INTERVAL 0x0018 // 30ms (30 / 1.25) - -/*============================================================================== - * GLOBAL VARIABLES - *============================================================================*/ - -#ifdef FIRMATA_SERIAL_FEATURE -SerialFirmata serialFeature; -#endif - -/* analog inputs */ -int analogInputsToReport = 0; // bitwise array to store pin reporting - -/* digital input ports */ -byte reportPINs[TOTAL_PORTS]; // 1 = report this port, 0 = silence -byte previousPINs[TOTAL_PORTS]; // previous 8 bits sent - -/* pins configuration */ -byte portConfigInputs[TOTAL_PORTS]; // each bit: 1 = pin in INPUT, 0 = anything else - -/* timer variables */ -unsigned long currentMillis; // store the current value from millis() -unsigned long previousMillis; // for comparison with currentMillis -unsigned int samplingInterval = 19; // how often to run the main loop (in ms) - -/* i2c data */ -struct i2c_device_info { - byte addr; - int reg; - byte bytes; - byte stopTX; -}; - -/* for i2c read continuous more */ -i2c_device_info query[I2C_MAX_QUERIES]; - -byte i2cRxData[64]; -boolean isI2CEnabled = false; -signed char queryIndex = -1; -// default delay time between i2c read request and Wire.requestFrom() -unsigned int i2cReadDelayTime = 0; - -Servo servos[MAX_SERVOS]; -byte servoPinMap[TOTAL_PINS]; -byte detachedServos[MAX_SERVOS]; -byte detachedServoCount = 0; -byte servoCount = 0; - -boolean isResetting = false; - -// Forward declare a few functions to avoid compiler errors with older versions -// of the Arduino IDE. -void setPinModeCallback(byte, int); -void reportAnalogCallback(byte analogPin, int value); -void sysexCallback(byte, byte, byte*); - -/* utility functions */ -void wireWrite(byte data) -{ -#if ARDUINO >= 100 - Wire.write((byte)data); -#else - Wire.send(data); -#endif -} - -byte wireRead(void) -{ -#if ARDUINO >= 100 - return Wire.read(); -#else - return Wire.receive(); -#endif -} - -/*============================================================================== - * FUNCTIONS - *============================================================================*/ - -void attachServo(byte pin, int minPulse, int maxPulse) -{ - if (servoCount < MAX_SERVOS) { - // reuse indexes of detached servos until all have been reallocated - if (detachedServoCount > 0) { - servoPinMap[pin] = detachedServos[detachedServoCount - 1]; - if (detachedServoCount > 0) detachedServoCount--; - } else { - servoPinMap[pin] = servoCount; - servoCount++; - } - if (minPulse > 0 && maxPulse > 0) { - servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin), minPulse, maxPulse); - } else { - servos[servoPinMap[pin]].attach(PIN_TO_DIGITAL(pin)); - } - } else { - Firmata.sendString("Max servos attached"); - } -} - -void detachServo(byte pin) -{ - servos[servoPinMap[pin]].detach(); - // if we're detaching the last servo, decrement the count - // otherwise store the index of the detached servo - if (servoPinMap[pin] == servoCount && servoCount > 0) { - servoCount--; - } else if (servoCount > 0) { - // keep track of detached servos because we want to reuse their indexes - // before incrementing the count of attached servos - detachedServoCount++; - detachedServos[detachedServoCount - 1] = servoPinMap[pin]; - } - - servoPinMap[pin] = 255; -} - -void enableI2CPins() -{ - byte i; - // is there a faster way to do this? would probaby require importing - // Arduino.h to get SCL and SDA pins - for (i = 0; i < TOTAL_PINS; i++) { - if (IS_PIN_I2C(i)) { - // mark pins as i2c so they are ignore in non i2c data requests - setPinModeCallback(i, PIN_MODE_I2C); - } - } - - isI2CEnabled = true; - - Wire.begin(); -} - -/* disable the i2c pins so they can be used for other functions */ -void disableI2CPins() { - isI2CEnabled = false; - // disable read continuous mode for all devices - queryIndex = -1; -} - -void readAndReportData(byte address, int theRegister, byte numBytes, byte stopTX) { - // allow I2C requests that don't require a register read - // for example, some devices using an interrupt pin to signify new data available - // do not always require the register read so upon interrupt you call Wire.requestFrom() - if (theRegister != I2C_REGISTER_NOT_SPECIFIED) { - Wire.beginTransmission(address); - wireWrite((byte)theRegister); - Wire.endTransmission(stopTX); // default = true - // do not set a value of 0 - if (i2cReadDelayTime > 0) { - // delay is necessary for some devices such as WiiNunchuck - delayMicroseconds(i2cReadDelayTime); - } - } else { - theRegister = 0; // fill the register with a dummy value - } - - Wire.requestFrom(address, numBytes); // all bytes are returned in requestFrom - - // check to be sure correct number of bytes were returned by slave - if (numBytes < Wire.available()) { - Firmata.sendString("I2C: Too many bytes received"); - } else if (numBytes > Wire.available()) { - Firmata.sendString("I2C: Too few bytes received"); - } - - i2cRxData[0] = address; - i2cRxData[1] = theRegister; - - for (int i = 0; i < numBytes && Wire.available(); i++) { - i2cRxData[2 + i] = wireRead(); - } - - // send slave address, register and received bytes - Firmata.sendSysex(SYSEX_I2C_REPLY, numBytes + 2, i2cRxData); -} - -void outputPort(byte portNumber, byte portValue, byte forceSend) -{ - // pins not configured as INPUT are cleared to zeros - portValue = portValue & portConfigInputs[portNumber]; - // only send if the value is different than previously sent - if (forceSend || previousPINs[portNumber] != portValue) { - Firmata.sendDigitalPort(portNumber, portValue); - previousPINs[portNumber] = portValue; - } -} - -/* ----------------------------------------------------------------------------- - * check all the active digital inputs for change of state, then add any events - * to the Serial output queue using Serial.print() */ -void checkDigitalInputs(void) -{ - /* Using non-looping code allows constants to be given to readPort(). - * The compiler will apply substantial optimizations if the inputs - * to readPort() are compile-time constants. */ - if (TOTAL_PORTS > 0 && reportPINs[0]) outputPort(0, readPort(0, portConfigInputs[0]), false); - if (TOTAL_PORTS > 1 && reportPINs[1]) outputPort(1, readPort(1, portConfigInputs[1]), false); - if (TOTAL_PORTS > 2 && reportPINs[2]) outputPort(2, readPort(2, portConfigInputs[2]), false); - if (TOTAL_PORTS > 3 && reportPINs[3]) outputPort(3, readPort(3, portConfigInputs[3]), false); - if (TOTAL_PORTS > 4 && reportPINs[4]) outputPort(4, readPort(4, portConfigInputs[4]), false); - if (TOTAL_PORTS > 5 && reportPINs[5]) outputPort(5, readPort(5, portConfigInputs[5]), false); - if (TOTAL_PORTS > 6 && reportPINs[6]) outputPort(6, readPort(6, portConfigInputs[6]), false); - if (TOTAL_PORTS > 7 && reportPINs[7]) outputPort(7, readPort(7, portConfigInputs[7]), false); - if (TOTAL_PORTS > 8 && reportPINs[8]) outputPort(8, readPort(8, portConfigInputs[8]), false); - if (TOTAL_PORTS > 9 && reportPINs[9]) outputPort(9, readPort(9, portConfigInputs[9]), false); - if (TOTAL_PORTS > 10 && reportPINs[10]) outputPort(10, readPort(10, portConfigInputs[10]), false); - if (TOTAL_PORTS > 11 && reportPINs[11]) outputPort(11, readPort(11, portConfigInputs[11]), false); - if (TOTAL_PORTS > 12 && reportPINs[12]) outputPort(12, readPort(12, portConfigInputs[12]), false); - if (TOTAL_PORTS > 13 && reportPINs[13]) outputPort(13, readPort(13, portConfigInputs[13]), false); - if (TOTAL_PORTS > 14 && reportPINs[14]) outputPort(14, readPort(14, portConfigInputs[14]), false); - if (TOTAL_PORTS > 15 && reportPINs[15]) outputPort(15, readPort(15, portConfigInputs[15]), false); -} - -// ----------------------------------------------------------------------------- -/* sets the pin mode to the correct state and sets the relevant bits in the - * two bit-arrays that track Digital I/O and PWM status - */ -void setPinModeCallback(byte pin, int mode) -{ - if (Firmata.getPinMode(pin) == PIN_MODE_IGNORE) - return; - - if (Firmata.getPinMode(pin) == PIN_MODE_I2C && isI2CEnabled && mode != PIN_MODE_I2C) { - // disable i2c so pins can be used for other functions - // the following if statements should reconfigure the pins properly - disableI2CPins(); - } - if (IS_PIN_DIGITAL(pin) && mode != PIN_MODE_SERVO) { - if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].attached()) { - detachServo(pin); - } - } - if (IS_PIN_ANALOG(pin)) { - reportAnalogCallback(PIN_TO_ANALOG(pin), mode == PIN_MODE_ANALOG ? 1 : 0); // turn on/off reporting - } - if (IS_PIN_DIGITAL(pin)) { - if (mode == INPUT || mode == PIN_MODE_PULLUP) { - portConfigInputs[pin / 8] |= (1 << (pin & 7)); - } else { - portConfigInputs[pin / 8] &= ~(1 << (pin & 7)); - } - } - Firmata.setPinState(pin, 0); - switch (mode) { - case PIN_MODE_ANALOG: - if (IS_PIN_ANALOG(pin)) { - if (IS_PIN_DIGITAL(pin)) { - pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver -#if ARDUINO <= 100 - // deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.6 - digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups -#endif - } - Firmata.setPinMode(pin, PIN_MODE_ANALOG); - } - break; - case INPUT: - if (IS_PIN_DIGITAL(pin)) { - pinMode(PIN_TO_DIGITAL(pin), INPUT); // disable output driver -#if ARDUINO <= 100 - // deprecated since Arduino 1.0.1 - TODO: drop support in Firmata 2.6 - digitalWrite(PIN_TO_DIGITAL(pin), LOW); // disable internal pull-ups -#endif - Firmata.setPinMode(pin, INPUT); - } - break; - case PIN_MODE_PULLUP: - if (IS_PIN_DIGITAL(pin)) { - pinMode(PIN_TO_DIGITAL(pin), INPUT_PULLUP); - Firmata.setPinMode(pin, PIN_MODE_PULLUP); - Firmata.setPinState(pin, 1); - } - break; - case OUTPUT: - if (IS_PIN_DIGITAL(pin)) { - if (Firmata.getPinMode(pin) == PIN_MODE_PWM) { - // Disable PWM if pin mode was previously set to PWM. - digitalWrite(PIN_TO_DIGITAL(pin), LOW); - } - pinMode(PIN_TO_DIGITAL(pin), OUTPUT); - Firmata.setPinMode(pin, OUTPUT); - } - break; - case PIN_MODE_PWM: - if (IS_PIN_PWM(pin)) { - pinMode(PIN_TO_PWM(pin), OUTPUT); - analogWrite(PIN_TO_PWM(pin), 0); - Firmata.setPinMode(pin, PIN_MODE_PWM); - } - break; - case PIN_MODE_SERVO: - if (IS_PIN_DIGITAL(pin)) { - Firmata.setPinMode(pin, PIN_MODE_SERVO); - if (servoPinMap[pin] == 255 || !servos[servoPinMap[pin]].attached()) { - // pass -1 for min and max pulse values to use default values set - // by Servo library - attachServo(pin, -1, -1); - } - } - break; - case PIN_MODE_I2C: - if (IS_PIN_I2C(pin)) { - // mark the pin as i2c - // the user must call I2C_CONFIG to enable I2C for a device - Firmata.setPinMode(pin, PIN_MODE_I2C); - } - break; - case PIN_MODE_SERIAL: -#ifdef FIRMATA_SERIAL_FEATURE - serialFeature.handlePinMode(pin, PIN_MODE_SERIAL); -#endif - break; - default: - Firmata.sendString("Unknown pin mode"); // TODO: put error msgs in EEPROM - } - // TODO: save status to EEPROM here, if changed -} - -/* - * Sets the value of an individual pin. Useful if you want to set a pin value but - * are not tracking the digital port state. - * Can only be used on pins configured as OUTPUT. - * Cannot be used to enable pull-ups on Digital INPUT pins. - */ -void setPinValueCallback(byte pin, int value) -{ - if (pin < TOTAL_PINS && IS_PIN_DIGITAL(pin)) { - if (Firmata.getPinMode(pin) == OUTPUT) { - Firmata.setPinState(pin, value); - digitalWrite(PIN_TO_DIGITAL(pin), value); - } - } -} - -void analogWriteCallback(byte pin, int value) -{ - if (pin < TOTAL_PINS) { - switch (Firmata.getPinMode(pin)) { - case PIN_MODE_SERVO: - if (IS_PIN_DIGITAL(pin)) - servos[servoPinMap[pin]].write(value); - Firmata.setPinState(pin, value); - break; - case PIN_MODE_PWM: - if (IS_PIN_PWM(pin)) - analogWrite(PIN_TO_PWM(pin), value); - Firmata.setPinState(pin, value); - break; - } - } -} - -void digitalWriteCallback(byte port, int value) -{ - byte pin, lastPin, pinValue, mask = 1, pinWriteMask = 0; - - if (port < TOTAL_PORTS) { - // create a mask of the pins on this port that are writable. - lastPin = port * 8 + 8; - if (lastPin > TOTAL_PINS) lastPin = TOTAL_PINS; - for (pin = port * 8; pin < lastPin; pin++) { - // do not disturb non-digital pins (eg, Rx & Tx) - if (IS_PIN_DIGITAL(pin)) { - // do not touch pins in PWM, ANALOG, SERVO or other modes - if (Firmata.getPinMode(pin) == OUTPUT || Firmata.getPinMode(pin) == INPUT) { - pinValue = ((byte)value & mask) ? 1 : 0; - if (Firmata.getPinMode(pin) == OUTPUT) { - pinWriteMask |= mask; - } else if (Firmata.getPinMode(pin) == INPUT && pinValue == 1 && Firmata.getPinState(pin) != 1) { - // only handle INPUT here for backwards compatibility -#if ARDUINO > 100 - pinMode(pin, INPUT_PULLUP); -#else - // only write to the INPUT pin to enable pullups if Arduino v1.0.0 or earlier - pinWriteMask |= mask; -#endif - } - Firmata.setPinState(pin, pinValue); - } - } - mask = mask << 1; - } - writePort(port, (byte)value, pinWriteMask); - } -} - - -// ----------------------------------------------------------------------------- -/* sets bits in a bit array (int) to toggle the reporting of the analogIns - */ -//void FirmataClass::setAnalogPinReporting(byte pin, byte state) { -//} -void reportAnalogCallback(byte analogPin, int value) -{ - if (analogPin < TOTAL_ANALOG_PINS) { - if (value == 0) { - analogInputsToReport = analogInputsToReport & ~ (1 << analogPin); - } else { - analogInputsToReport = analogInputsToReport | (1 << analogPin); - // prevent during system reset or all analog pin values will be reported - // which may report noise for unconnected analog pins - if (!isResetting) { - // Send pin value immediately. This is helpful when connected via - // ethernet, wi-fi or bluetooth so pin states can be known upon - // reconnecting. - Firmata.sendAnalog(analogPin, analogRead(analogPin)); - } - } - } - // TODO: save status to EEPROM here, if changed -} - -void reportDigitalCallback(byte port, int value) -{ - if (port < TOTAL_PORTS) { - reportPINs[port] = (byte)value; - // Send port value immediately. This is helpful when connected via - // ethernet, wi-fi or bluetooth so pin states can be known upon - // reconnecting. - if (value) outputPort(port, readPort(port, portConfigInputs[port]), true); - } - // do not disable analog reporting on these 8 pins, to allow some - // pins used for digital, others analog. Instead, allow both types - // of reporting to be enabled, but check if the pin is configured - // as analog when sampling the analog inputs. Likewise, while - // scanning digital pins, portConfigInputs will mask off values from any - // pins configured as analog -} - -/*============================================================================== - * SYSEX-BASED commands - *============================================================================*/ - -void sysexCallback(byte command, byte argc, byte *argv) -{ - byte mode; - byte stopTX; - byte slaveAddress; - byte data; - int slaveRegister; - unsigned int delayTime; - - switch (command) { - case I2C_REQUEST: - mode = argv[1] & I2C_READ_WRITE_MODE_MASK; - if (argv[1] & I2C_10BIT_ADDRESS_MODE_MASK) { - Firmata.sendString("10-bit addressing not supported"); - return; - } - else { - slaveAddress = argv[0]; - } - - // need to invert the logic here since 0 will be default for client - // libraries that have not updated to add support for restart tx - if (argv[1] & I2C_END_TX_MASK) { - stopTX = I2C_RESTART_TX; - } - else { - stopTX = I2C_STOP_TX; // default - } - - switch (mode) { - case I2C_WRITE: - Wire.beginTransmission(slaveAddress); - for (byte i = 2; i < argc; i += 2) { - data = argv[i] + (argv[i + 1] << 7); - wireWrite(data); - } - Wire.endTransmission(); - delayMicroseconds(70); - break; - case I2C_READ: - if (argc == 6) { - // a slave register is specified - slaveRegister = argv[2] + (argv[3] << 7); - data = argv[4] + (argv[5] << 7); // bytes to read - } - else { - // a slave register is NOT specified - slaveRegister = I2C_REGISTER_NOT_SPECIFIED; - data = argv[2] + (argv[3] << 7); // bytes to read - } - readAndReportData(slaveAddress, (int)slaveRegister, data, stopTX); - break; - case I2C_READ_CONTINUOUSLY: - if ((queryIndex + 1) >= I2C_MAX_QUERIES) { - // too many queries, just ignore - Firmata.sendString("too many queries"); - break; - } - if (argc == 6) { - // a slave register is specified - slaveRegister = argv[2] + (argv[3] << 7); - data = argv[4] + (argv[5] << 7); // bytes to read - } - else { - // a slave register is NOT specified - slaveRegister = (int)I2C_REGISTER_NOT_SPECIFIED; - data = argv[2] + (argv[3] << 7); // bytes to read - } - queryIndex++; - query[queryIndex].addr = slaveAddress; - query[queryIndex].reg = slaveRegister; - query[queryIndex].bytes = data; - query[queryIndex].stopTX = stopTX; - break; - case I2C_STOP_READING: - byte queryIndexToSkip; - // if read continuous mode is enabled for only 1 i2c device, disable - // read continuous reporting for that device - if (queryIndex <= 0) { - queryIndex = -1; - } else { - queryIndexToSkip = 0; - // if read continuous mode is enabled for multiple devices, - // determine which device to stop reading and remove it's data from - // the array, shifiting other array data to fill the space - for (byte i = 0; i < queryIndex + 1; i++) { - if (query[i].addr == slaveAddress) { - queryIndexToSkip = i; - break; - } - } - - for (byte i = queryIndexToSkip; i < queryIndex + 1; i++) { - if (i < I2C_MAX_QUERIES) { - query[i].addr = query[i + 1].addr; - query[i].reg = query[i + 1].reg; - query[i].bytes = query[i + 1].bytes; - query[i].stopTX = query[i + 1].stopTX; - } - } - queryIndex--; - } - break; - default: - break; - } - break; - case I2C_CONFIG: - delayTime = (argv[0] + (argv[1] << 7)); - - if (delayTime > 0) { - i2cReadDelayTime = delayTime; - } - - if (!isI2CEnabled) { - enableI2CPins(); - } - - break; - case SERVO_CONFIG: - if (argc > 4) { - // these vars are here for clarity, they'll optimized away by the compiler - byte pin = argv[0]; - int minPulse = argv[1] + (argv[2] << 7); - int maxPulse = argv[3] + (argv[4] << 7); - - if (IS_PIN_DIGITAL(pin)) { - if (servoPinMap[pin] < MAX_SERVOS && servos[servoPinMap[pin]].attached()) { - detachServo(pin); - } - attachServo(pin, minPulse, maxPulse); - setPinModeCallback(pin, PIN_MODE_SERVO); - } - } - break; - case SAMPLING_INTERVAL: - if (argc > 1) { - samplingInterval = argv[0] + (argv[1] << 7); - if (samplingInterval < MINIMUM_SAMPLING_INTERVAL) { - samplingInterval = MINIMUM_SAMPLING_INTERVAL; - } - } else { - //Firmata.sendString("Not enough data"); - } - break; - case EXTENDED_ANALOG: - if (argc > 1) { - int val = argv[1]; - if (argc > 2) val |= (argv[2] << 7); - if (argc > 3) val |= (argv[3] << 14); - analogWriteCallback(argv[0], val); - } - break; - case CAPABILITY_QUERY: - Firmata.write(START_SYSEX); - Firmata.write(CAPABILITY_RESPONSE); - for (byte pin = 0; pin < TOTAL_PINS; pin++) { - if (IS_PIN_DIGITAL(pin)) { - Firmata.write((byte)INPUT); - Firmata.write(1); - Firmata.write((byte)PIN_MODE_PULLUP); - Firmata.write(1); - Firmata.write((byte)OUTPUT); - Firmata.write(1); - } - if (IS_PIN_ANALOG(pin)) { - Firmata.write(PIN_MODE_ANALOG); - Firmata.write(10); // 10 = 10-bit resolution - } - if (IS_PIN_PWM(pin)) { - Firmata.write(PIN_MODE_PWM); - Firmata.write(8); // 8 = 8-bit resolution - } - if (IS_PIN_DIGITAL(pin)) { - Firmata.write(PIN_MODE_SERVO); - Firmata.write(14); - } - if (IS_PIN_I2C(pin)) { - Firmata.write(PIN_MODE_I2C); - Firmata.write(1); // TODO: could assign a number to map to SCL or SDA - } -#ifdef FIRMATA_SERIAL_FEATURE - serialFeature.handleCapability(pin); -#endif - Firmata.write(127); - } - Firmata.write(END_SYSEX); - break; - case PIN_STATE_QUERY: - if (argc > 0) { - byte pin = argv[0]; - Firmata.write(START_SYSEX); - Firmata.write(PIN_STATE_RESPONSE); - Firmata.write(pin); - if (pin < TOTAL_PINS) { - Firmata.write(Firmata.getPinMode(pin)); - Firmata.write((byte)Firmata.getPinState(pin) & 0x7F); - if (Firmata.getPinState(pin) & 0xFF80) Firmata.write((byte)(Firmata.getPinState(pin) >> 7) & 0x7F); - if (Firmata.getPinState(pin) & 0xC000) Firmata.write((byte)(Firmata.getPinState(pin) >> 14) & 0x7F); - } - Firmata.write(END_SYSEX); - } - break; - case ANALOG_MAPPING_QUERY: - Firmata.write(START_SYSEX); - Firmata.write(ANALOG_MAPPING_RESPONSE); - for (byte pin = 0; pin < TOTAL_PINS; pin++) { - Firmata.write(IS_PIN_ANALOG(pin) ? PIN_TO_ANALOG(pin) : 127); - } - Firmata.write(END_SYSEX); - break; - - case SERIAL_MESSAGE: -#ifdef FIRMATA_SERIAL_FEATURE - serialFeature.handleSysex(command, argc, argv); -#endif - break; - } -} - -/*============================================================================== - * SETUP() - *============================================================================*/ - -void systemResetCallback() -{ - isResetting = true; - -#ifdef FIRMATA_SERIAL_FEATURE - serialFeature.reset(); -#endif - - if (isI2CEnabled) { - disableI2CPins(); - } - - for (byte i = 0; i < TOTAL_PORTS; i++) { - reportPINs[i] = false; // by default, reporting off - portConfigInputs[i] = 0; // until activated - previousPINs[i] = 0; - } - - for (byte i = 0; i < TOTAL_PINS; i++) { - // pins with analog capability default to analog input - // otherwise, pins default to digital output - if (IS_PIN_ANALOG(i)) { - // turns off pullup, configures everything - setPinModeCallback(i, PIN_MODE_ANALOG); - } else if (IS_PIN_DIGITAL(i)) { - // sets the output to 0, configures portConfigInputs - setPinModeCallback(i, OUTPUT); - } - - servoPinMap[i] = 255; - } - // by default, do not report any analog inputs - analogInputsToReport = 0; - - detachedServoCount = 0; - servoCount = 0; - - isResetting = false; -} - -void setup() -{ - DEBUG_BEGIN(9600); - - Firmata.setFirmwareVersion(FIRMATA_FIRMWARE_MAJOR_VERSION, FIRMATA_FIRMWARE_MINOR_VERSION); - - Firmata.attach(ANALOG_MESSAGE, analogWriteCallback); - Firmata.attach(DIGITAL_MESSAGE, digitalWriteCallback); - Firmata.attach(REPORT_ANALOG, reportAnalogCallback); - Firmata.attach(REPORT_DIGITAL, reportDigitalCallback); - Firmata.attach(SET_PIN_MODE, setPinModeCallback); - Firmata.attach(SET_DIGITAL_PIN_VALUE, setPinValueCallback); - Firmata.attach(START_SYSEX, sysexCallback); - Firmata.attach(SYSTEM_RESET, systemResetCallback); - - stream.setLocalName(FIRMATA_BLE_LOCAL_NAME); - - // set the BLE connection interval - this is the fastest interval you can read inputs - stream.setConnectionInterval(FIRMATA_BLE_MIN_INTERVAL, FIRMATA_BLE_MAX_INTERVAL); - // set how often the BLE TX buffer is flushed (if not full) - stream.setFlushInterval(FIRMATA_BLE_MAX_INTERVAL); - -#ifdef BLE_REQ - for (byte i = 0; i < TOTAL_PINS; i++) { - if (IS_IGNORE_BLE_PINS(i)) { - Firmata.setPinMode(i, PIN_MODE_IGNORE); - } - } -#endif - - stream.begin(); - Firmata.begin(stream); - - systemResetCallback(); // reset to default config -} - -/*============================================================================== - * LOOP() - *============================================================================*/ -void loop() -{ - byte pin, analogPin; - - // do not process data if no BLE connection is established - // poll will send the TX buffer at the specified flush interval or when the buffer is full - if (!stream.poll()) return; - - /* DIGITALREAD - as fast as possible, check for changes and output them to the - * Stream buffer using Stream.write() */ - checkDigitalInputs(); - - /* STREAMREAD - processing incoming messagse as soon as possible, while still - * checking digital inputs. */ - while (Firmata.available()) - Firmata.processInput(); - - currentMillis = millis(); - if (currentMillis - previousMillis > samplingInterval) { - previousMillis = currentMillis; - /* ANALOGREAD - do all analogReads() at the configured sampling interval */ - for (pin = 0; pin < TOTAL_PINS; pin++) { - if (IS_PIN_ANALOG(pin) && Firmata.getPinMode(pin) == PIN_MODE_ANALOG) { - analogPin = PIN_TO_ANALOG(pin); - if (analogInputsToReport & (1 << analogPin)) { - Firmata.sendAnalog(analogPin, analogRead(analogPin)); - } - } - } - // report i2c data for all device with read continuous mode enabled - if (queryIndex > -1) { - for (byte i = 0; i < queryIndex + 1; i++) { - readAndReportData(query[i].addr, query[i].reg, query[i].bytes, query[i].stopTX); - } - } - } - -#ifdef FIRMATA_SERIAL_FEATURE - serialFeature.update(); -#endif -} - -/* - Firmata is a generic protocol for communicating with microcontrollers - from software on a host computer. It is intended to work with - any host computer software package. - To download a host software package, please click on the following link - to open the list of Firmata client libraries in your default browser. - https://github.com/firmata/arduino#firmata-client-libraries - Copyright (C) 2006-2008 Hans-Christoph Steiner. All rights reserved. - Copyright (C) 2010-2011 Paul Stoffregen. All rights reserved. - Copyright (C) 2009 Shigeru Kobayashi. All rights reserved. - Copyright (C) 2009-2016 Jeff Hoefs. 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. - See file LICENSE.txt for further informations on licensing terms. - Last updated October 16th, 2016 -*/ - - diff --git a/libraries/CurieBLE/examples/test/CommunitySketches/StandardFirmataBLE/bleConfig.h b/libraries/CurieBLE/examples/test/CommunitySketches/StandardFirmataBLE/bleConfig.h deleted file mode 100644 index aeb96a81..00000000 --- a/libraries/CurieBLE/examples/test/CommunitySketches/StandardFirmataBLE/bleConfig.h +++ /dev/null @@ -1,112 +0,0 @@ -/*================================================================================================== - * BLE CONFIGURATION - * - * If you are using an Arduino 101, you do not need to make any changes to this file (unless you - * need a unique ble local name (see below). If you are using another supported BLE board or shield, - * follow the instructions for the specific board or shield below. - * - * Make sure you have the Intel Curie Boards package v1.0.6 or higher installed via the Arduino - * Boards Manager. - * - * Supported boards and shields: - * - Arduino 101 (recommended) - * - RedBearLab BLE Shield (v2) ** to be verified ** - * - RedBearLab BLE Nano ** works with modifications ** - * - *================================================================================================*/ - -// change this to a unique name per board if running StandardFirmataBLE on multiple boards -// within the same physical space -#define FIRMATA_BLE_LOCAL_NAME "FIRMATA" - -/* - * RedBearLab BLE Shield - * - * If you are using a RedBearLab BLE shield, uncomment the define below. - * Also, change the define for BLE_RST if you have the jumper set to pin 7 rather than pin 4. - * - * You will need to use the shield with an Arduino Zero, Due, Mega, or other board with sufficient - * Flash and RAM. Arduino Uno, Leonardo and other ATmega328p and Atmega32u4 boards to not have - * enough memory to run StandardFirmataBLE. - * - * TODO: verify if this works and with which boards it works. - * - * Test script: https://gist.github.com/soundanalogous/927360b797574ed50e27 - */ -//#define REDBEAR_BLE_SHIELD - -#ifdef REDBEAR_BLE_SHIELD -#include -#include -#include "utility/BLEStream.h" - -#define BLE_REQ 9 -#define BLE_RDY 8 -#define BLE_RST 4 // 4 or 7 via jumper on shield - -BLEStream stream(BLE_REQ, BLE_RDY, BLE_RST); -#endif - - -/*================================================================================================== - * END BLE CONFIGURATION - you should not need to change anything below this line - *================================================================================================*/ - -/* - * Arduino 101 - * - * Make sure you have the Intel Curie Boards package v1.0.6 or higher installed via the Arduino - * Boards Manager. - * - * Test script: https://gist.github.com/soundanalogous/927360b797574ed50e27 - */ -#ifdef _VARIANT_ARDUINO_101_X_ -#include -#include "BLEStream.h" -BLEStream stream; -#endif - - -/* - * RedBearLab BLE Nano (with default switch settings) - * - * Blocked on this issue: https://github.com/RedBearLab/nRF51822-Arduino/issues/46 - * Works with modifications. See comments at top of the test script referenced below. - * When the RBL nRF51822-Arduino library issue is resolved, this should work witout - * any modifications. - * - * Test script: https://gist.github.com/soundanalogous/d39bb3eb36333a0906df - * - * Note: If you have changed the solder jumpers on the Nano you may encounter issues since - * the pins are currently mapped in Firmata only for the default (factory) jumper settings. - */ -// #ifdef BLE_NANO -// #include -// #include "utility/BLEStream.h" -// BLEStream stream; -// #endif - - -/* - * RedBearLab Blend and Blend Micro - * - * StandardFirmataBLE requires too much Flash and RAM to run on the ATmega32u4-based Blend - * and Blend Micro boards. It may work with ConfigurableFirmata selecting only analog and/or - * digital I/O. - */ -// #if defined(BLEND_MICRO) || defined(BLEND) -// #include -// #include -// #include "utility/BLEStream.h" - -// #define BLE_REQ 6 -// #define BLE_RDY 7 -// #define BLE_RST 4 - -// BLEStream stream(BLE_REQ, BLE_RDY, BLE_RST); -// #endif - - -#if defined(BLE_REQ) && defined(BLE_RDY) && defined(BLE_RST) -#define IS_IGNORE_BLE_PINS(p) ((p) == BLE_REQ || (p) == BLE_RDY || (p) == BLE_RST) -#endif diff --git a/libraries/CurieBLE/examples/test/IMUBleCentral/IMUBleCentral.ino b/libraries/CurieBLE/examples/test/IMUBleCentral/IMUBleCentral.ino deleted file mode 100644 index 739a8b05..00000000 --- a/libraries/CurieBLE/examples/test/IMUBleCentral/IMUBleCentral.ino +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation. All rights reserved. - * See the bottom of this file for the license terms. - */ - -/* - * Sketch: IMUBleCentral.ino - * - * Description: - * This sketch will receive the notifications and output the - * received data in the serial monitor. It also illustrates - * using a non-typed characteristic. - * - * Notes: - * - * - Expected Peripheral name: Imu - * - Expected Peripheral Characteristic: F7580003-153E-D4F6-F26D-43D8D98EEB13 - * - Expected Peripheral sketch: IMUBleNotification.ino - */ - -#include - -#define LED_PIN 13 -#define MAX_IMU_RECORD 1 - -// define a structure that will serve as buffer for holding IMU data - -typedef struct { - int index; - unsigned int slot[3]; -} imuFrameType; - -imuFrameType imuBuf[MAX_IMU_RECORD]; - -void setup() -{ - // This is set to higher baud rate because accelerometer data changes very quickly - Serial.begin(9600); // initialize serial communication - while (!Serial); - pinMode(LED_PIN, OUTPUT); // initialize the LED on pin 13 to indicate when a central is connected - - /* Now activate the BLE device. It will start continuously transmitting BLE - advertising packets and will be visible to remote BLE central devices - until it receives a new connection */ - BLE.begin(); - Serial.println(BLE.address()); - - BLE.scanForName("Imu"); -} - - -void loop() -{ - BLEDevice peripheral = BLE.available(); - //pr_debug(LOG_MODULE_BLE, "%s-%d",__FUNCTION__, __LINE__); - if (peripheral) - { - Serial.println(peripheral.address()); - BLE.stopScan(); - delay (1000); - // central connected to peripheral - controlImu(peripheral); - delay (4000); - BLE.scanForName("Imu"); - } -} - -void controlImu(BLEDevice peripheral) -{ - static bool discovered = false; - // connect to the peripheral - Serial.print("Connecting ... "); - Serial.println(peripheral.address()); - - if (peripheral.connect()) - { - Serial.print("Connected: "); - Serial.println(peripheral.address()); - } - else - { - Serial.println("Failed to connect!"); - return; - } - - peripheral.discoverAttributes(); - - BLECharacteristic bleImuChar = peripheral.characteristic("F7580003-153E-D4F6-F26D-43D8D98EEB13"); - - if (!bleImuChar) - { - peripheral.disconnect(); - Serial.println("Peripheral does not have IMU characteristic!"); - delay(5000); - return; - } - bleImuChar.subscribe(); - - - discovered = false; - while (peripheral.connected()) - { - if (bleImuChar.valueUpdated()) - { - const unsigned char *cvalue = bleImuChar.value(); - const imuFrameType *value = (const imuFrameType *)cvalue; - Serial.print("\r\nCharacteristic event, written: "); - Serial.print(value->index); - Serial.print("\t"); - Serial.print(value->slot[0]); - Serial.print("\t"); - Serial.print(value->slot[1]); - Serial.print("\t"); - Serial.println(value->slot[2]); - } - } - Serial.print("Disconnected"); - Serial.println(peripheral.address()); -} - - -/* - Copyright (c) 2016 Arduino LLC. All right 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 St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - diff --git a/libraries/CurieBLE/examples/test/IMUBleNotification/IMUBleNotification.ino b/libraries/CurieBLE/examples/test/IMUBleNotification/IMUBleNotification.ino deleted file mode 100644 index e8ad758b..00000000 --- a/libraries/CurieBLE/examples/test/IMUBleNotification/IMUBleNotification.ino +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation. All rights reserved. - * See the bottom of this file for the license terms. - */ - -/* - * Sketch: IMUBleNotification.ino - * - * Description: - * This is a Peripheral sketch that reads IMU data from sensor and sends - * via notifications to a connected Central. - * - * Notes: - * - * - This sketch is inteneded to pair up with IMUBleCentral.ino. - * - */ - -#include -#include - -#define MAX_IMU_RECORD 1 - -typedef struct { - int index; - unsigned int slot[3]; -} imuFrameType; - -// Buffer to hold IMU data -imuFrameType imuBuf[MAX_IMU_RECORD]; - -unsigned seqNum = 0; - -BLEService bleImuService("F7580001-153E-D4F6-F26D-43D8D98EEB13"); // Tx IMU data Characteristic -BLECharacteristic bleImuChar("F7580003-153E-D4F6-F26D-43D8D98EEB13", // standard 128-bit characteristic UUID - BLERead | BLENotify, sizeof(imuBuf)); // remote clients will be able to - // get notifications if this characteristic changes -void setup() -{ - Serial.begin(9600); // initialize serial communication - while (!Serial); - pinMode(13, OUTPUT); // initialize the LED on pin 13 to indicate when a central is connected - - - BLE.begin(); - CurieIMU.begin(); - /* Set a local name for the BLE device - This name will appear in advertising packets - and can be used by remote devices to identify this BLE device - The name can be changed but maybe be truncated based on space left in advertisement packet */ - BLE.setLocalName("Imu"); - BLE.setAdvertisedServiceUuid(bleImuService.uuid()); // add the service UUID - - BLE.addService(bleImuService); // Add the Imu service - bleImuService.addCharacteristic(bleImuChar); // add the Imu characteristic - - /* Now activate the BLE device. It will start continuously transmitting BLE - advertising packets and will be visible to remote BLE central devices - until it receives a new connection */ - // Start the IMU - BLE.advertise(); -} - -void loop() -{ - // listen for BLE peripherals to connect: - // Since we are a peripheral we need a central object to connect to - BLEDevice central = BLE.central(); - - // if a central is connected to peripheral: - if (central) - { - Serial.print("Connected to central: "); - // print the central's MAC address: - Serial.println(central.address()); - - Serial.print("IMU buffer size: "); - Serial.println(sizeof(imuBuf)); - - // turn on the LED to indicate the connection: - digitalWrite(13, HIGH); - - long currentMillis, sentTime; - - // Send IMU data as long as the central is still connected - currentMillis = sentTime = millis(); - while (central.connected()) - { - // Take IMU data every 100 msec - if ((millis() - sentTime) >= 1000) - { - recordImuData(0); - sentTime = millis(); - bleImuChar.setValue((unsigned char *)&(imuBuf[0]), sizeof(imuBuf)); - } - } // end of while loop - - // when the central disconnects, turn off the LED: - digitalWrite(13, LOW); - Serial.print("Disconnected from central: "); - Serial.println(central.address()); - } -} - -// This function records the IMU data that we send to the central -void recordImuData(int index) -{ - /* Read IMU data. - */ - int ax, ay, az; - int gx, gy, gz; - - imuBuf[index].index = seqNum++; - CurieIMU.readMotionSensor(ax, ay, az, gx, gy, gz); - - // Encode the data into the buffer - imuBuf[index].slot[0] = (unsigned int)((ax << 16) | (ay & 0x0FFFF)); - imuBuf[index].slot[1] = (unsigned int)((az << 16) | (gx & 0x0FFFF)); - imuBuf[index].slot[2] = (unsigned int)((gy << 16) | (gz & 0x0FFFF)); -} - - -/* - Copyright (c) 2016 Arduino LLC. All right 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 St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - diff --git a/libraries/CurieBLE/examples/test/PeripheralDouble/PeripheralDouble.ino b/libraries/CurieBLE/examples/test/PeripheralDouble/PeripheralDouble.ino deleted file mode 100644 index 658822e2..00000000 --- a/libraries/CurieBLE/examples/test/PeripheralDouble/PeripheralDouble.ino +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation. All rights reserved. - * See the bottom of this file for the license terms. - */ - -/* - * Sketch: PeripheralDouble.ino - * - * Description: - * This is a Peripheral sketch that has a Characteristic of double. - * It demonstrates the usage of double in a BLE exchange. - * - * Notes: - * - * - Peripheral Characteristic: 19b20001e8f2537e4f6cd104768a1214 - */ - -#include - -// LED pin -#define LED_PIN 13 - -// create service -BLEService dataService("19b20000e8f2537e4f6cd104768a1214"); - -// create data characteristic -BLEDoubleCharacteristic doubleCharacteristic("19b20001e8f2537e4f6cd104768a1214", BLERead | BLEWrite); - -void setup() { - Serial.begin(9600); - - // set LED pin to output mode - pinMode(LED_PIN, OUTPUT); - - // begin initialization - BLE.begin(); - Serial.println(BLE.address()); - - // set advertised local name and service UUID - BLE.setLocalName("DataTest"); - - dataService.addCharacteristic(doubleCharacteristic); - - // add service and characteristic - BLE.addService(dataService); - - BLE.advertise(); - - Serial.println(F("BLE Test Double Peripheral")); -} - -void loop() { - BLEDevice central = BLE.central(); - double test_value = 0.1; - - if (central) { - // central connected to peripheral - Serial.print(F("Connected to central: ")); - Serial.println(central.address()); - - while (central.connected()) - { - // central still connected to peripheral - doubleCharacteristic.writeDouble(test_value); - test_value += 0.3; - delay(2000); - } - - // central disconnected - Serial.print(F("Disconnected from central: ")); - Serial.println(central.address()); - } -} - - -/* - Arduino BLE Peripheral Double read/write test example - Copyright (c) 2016 Arduino LLC. All right 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 St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - diff --git a/libraries/CurieBLE/examples/test/connupdateperipheral/connupdateperipheral.ino b/libraries/CurieBLE/examples/test/connupdateperipheral/connupdateperipheral.ino deleted file mode 100644 index f8605f25..00000000 --- a/libraries/CurieBLE/examples/test/connupdateperipheral/connupdateperipheral.ino +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2017 Intel Corporation. All rights reserved. - * See the bottom of this file for the license terms. - */ - -/* - * Sketch: connupdateperipheral.ino - * - * Description: - * This is a Peripheral sketch that is based on the Arduino LED - * control sketch. The purpose of this sketch is to exercise - * the changing of Connection Interval as a Peripheral. The Central - * writes to the Characteristic to turn the LED on and off similar - * to the original sketch. However, when the LED is turned off, - * this sketch will change the connection interval to a new - * value and, thus, forcing a re-connection. - * - * Notes: - * - * - This sketch is based on the Arduino BLE Peripheral LED example. - * Please refer to licensing info at the bottom of this file. - */ - -#include - -// LED pin -#define LED_PIN 13 - -// create service -BLEService ledService("19b10000e8f2537e4f6cd104768a1214"); - -// create switch characteristic -BLECharCharacteristic switchCharacteristic("19b10001e8f2537e4f6cd104768a1214", BLERead | BLEWrite); - -BLEDescriptor switchDescriptor("2901", "switch"); - - -void bleCentralConnectionParameterUpdateHandler(BLEDevice central) { - Serial1.println("Updated connection parameter"); - Serial1.println("-----------------------"); - - // print address - Serial1.print("Address: "); - Serial1.println(central.address()); - - Serial1.print("Interval: "); - Serial1.println(central.getConnectionInterval()); - Serial1.print("Timeout: "); - Serial1.println(central.getConnectionTimeout()); - Serial1.print("Latency: "); - Serial1.println(central.getConnectionLatency()); - - //Serial1.println(); -} - -void setup() { - Serial.begin(9600); - Serial1.begin(115200); - - // set LED pin to output mode - pinMode(LED_PIN, OUTPUT); - - // begin initialization - BLE.begin(); - Serial1.println(BLE.address()); - - // set advertised local name and service UUID - BLE.setLocalName("LED"); - BLE.setAdvertisedServiceUuid(ledService.uuid()); - - switchCharacteristic.addDescriptor(switchDescriptor); - ledService.addCharacteristic(switchCharacteristic); - - // add service and characteristic - BLE.addService(ledService); - - //Register callbacks - BLE.setEventHandler(BLEConParamUpdate, bleCentralConnectionParameterUpdateHandler); - - BLE.advertise(); - - Serial1.println(F("BLE LED Peripheral")); -} - -void loop() { - BLEDevice central = BLE.central(); - - if (central) { - // central connected to peripheral - Serial1.print(F("Connected to central: ")); - Serial1.println(central.address()); - static int connection_interval = 15; - - while (central.connected()) { - // central still connected to peripheral - if (switchCharacteristic.written()) { - // central wrote new value to characteristic, update LED - if (switchCharacteristic.value()) { - Serial1.println(F("LED on")); - digitalWrite(LED_PIN, HIGH); - connection_interval++; - } else { - Serial1.println(F("LED off")); - digitalWrite(LED_PIN, LOW); - delay(100); - // The peripheral update the connection interval - // If want central update the connection interval - // comment the below line - central.setConnectionInterval(connection_interval, connection_interval); - } - } - } - - // central disconnected - Serial1.print(F("Disconnected from central: ")); - Serial1.println(central.address()); - } -} - -/* - Arduino BLE Peripheral LED example - Copyright (c) 2016 Arduino LLC. All right 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 St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - diff --git a/libraries/CurieBLE/examples/test/discoveratperipheral/discoveratperipheral.ino b/libraries/CurieBLE/examples/test/discoveratperipheral/discoveratperipheral.ino deleted file mode 100644 index 8de71767..00000000 --- a/libraries/CurieBLE/examples/test/discoveratperipheral/discoveratperipheral.ino +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright (c) 2016 Intel Corporation. All rights reserved. - * See the bottom of this file for the license terms. - */ - -/* - * Sketch: discoveratperipheral.ino. - * - * Description: - * This is a BLE Central sketch that looks for a particular - * Characteristic in a connected Peripheral to write to. The - * Peripheral with the special Characteristic will blink its - * LED. - * - * Notes: - * - This sketch is Arduino BLE Peripheral LED example. - * Please see licensing at the bottom of this file. - * - Expected Peripheral Characteristic: 19b10000e8f2537e4f6cd104768a1214 - */ - -#include - -// LED pin -#define LED_PIN 13 - -// create service -BLEService ledService("19b10000e8f2537e4f6cd104768a1214"); - -void setup() { - Serial.begin(9600); - - // set LED pin to output mode - pinMode(LED_PIN, OUTPUT); - - // begin initialization - BLE.begin(); - Serial.println(BLE.address()); - - // set advertised local name and service UUID - BLE.setLocalName("LED"); - - BLE.advertise(); - - Serial.println(F("BLE LED Peripheral")); -} - -void loop() { - BLEDevice central = BLE.central(); - - if (central) { - // central connected to peripheral - Serial.print(F("Connected to central: ")); - Serial.println(central.address()); - - controlLed(central); - // central disconnected - Serial.print(F("Disconnected from central: ")); - Serial.println(central.address()); - } -} - -void controlLed(BLEDevice ¢ral) -{ - if (central.discoverAttributes() == false) - { - Serial.println("Discover failed, Disconnecting..."); - central.disconnect(); - return; - } - - BLECharacteristic ledCharacteristic = central.characteristic("19b10101-e8f2-537e-4f6c-d104768a1214"); - - if (!ledCharacteristic) - { - central.disconnect(); - //while(1) - { - Serial.println("Central does not have LED characteristic!"); - delay(5000); - } - return; - } - - ledCharacteristic.subscribe(); - - unsigned char ledstate = 0; - - while (central.connected()) - { - if (ledstate == 1) - { - ledstate = 0; - } - else - { - ledstate = 1; - } - ledCharacteristic.write(&ledstate, sizeof(ledstate)); - delay(5000); - } - Serial.print("Disconnected"); - Serial.println(central.address()); -} - - -/* - Arduino BLE Peripheral LED example - Copyright (c) 2016 Arduino LLC. All right 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 St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - diff --git a/libraries/CurieBLE/examples/test/profileatcentral/profileatcentral.ino b/libraries/CurieBLE/examples/test/profileatcentral/profileatcentral.ino deleted file mode 100644 index 2fe20520..00000000 --- a/libraries/CurieBLE/examples/test/profileatcentral/profileatcentral.ino +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (c) 2017 Intel Corporation. All rights reserved. - * See the bottom of this file for the license terms. - */ - -/* - * Sketch: profileatcentral.ino - * - * Description: - * This is a BLE Central sketch that demostrates the setting of the - * BLE descriptor. - * - * Notes: - * - This sketch is based on the Arduino BLE Peripheral LED example. - * Please refer to licensing agreement at the bottom of this file. - */ - -#include "CurieBLE.h" -#include -// LED pin -#define LED_PIN 13 -BLEService ledService("19b10100e8f2537e4f6cd104768a1214"); - -BLECharacteristic switchCharacteristic("19b10101e8f2537e4f6cd104768a1214", BLERead | BLEWrite | BLENotify, 1); - -BLEDescriptor switchDescriptor("2901", "switch"); - -void setup() { - Serial.begin(115200); - - // set LED pin to output mode - pinMode(LED_PIN, OUTPUT); - - // begin initialization - BLE.begin(); - Serial.println(BLE.address()); - ledService.addCharacteristic(switchCharacteristic); - switchCharacteristic.addDescriptor(switchDescriptor); - BLE.addService(ledService); - - BLE.scanForName("LED"); -} - - -void loop() { - BLEDevice peripheral = BLE.available(); - if (peripheral) - { - Serial.println(peripheral.address()); - - BLE.stopScan(); - - if (peripheral.connect()) - { - Serial.print("Connected: "); - Serial.println(peripheral.address()); - while (peripheral.connected()) - { - delay (1000); - } - } - else - { - Serial.println("Failed to connect!"); - } - delay (4000); - BLE.scanForName("LED"); - } -} - - -/* - Arduino BLE Peripheral LED example - Copyright (c) 2016 Arduino LLC. All right 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 St, Fifth Floor, Boston, MA 02110-1301 USA -*/ - - diff --git a/libraries/CurieBLE/keywords.txt b/libraries/CurieBLE/keywords.txt index a98db39d..91104ee0 100644 --- a/libraries/CurieBLE/keywords.txt +++ b/libraries/CurieBLE/keywords.txt @@ -5,7 +5,7 @@ ####################################### # Datatypes (KEYWORD1) ####################################### - +CurieBLE KEYWORD1 BLEAttributeWithValue KEYWORD1 BLEBoolCharacteristic KEYWORD1 BLEByteCharacteristic KEYWORD1 diff --git a/libraries/CurieBLE/src/BLEDevice.cpp b/libraries/CurieBLE/src/BLEDevice.cpp index b894e3c1..f4713cf8 100644 --- a/libraries/CurieBLE/src/BLEDevice.cpp +++ b/libraries/CurieBLE/src/BLEDevice.cpp @@ -85,7 +85,12 @@ void BLEDevice::poll() } void BLEDevice::end() -{} +{ + if (BLEUtils::isLocalBLE(*this)) + { + BLEDeviceManager::instance()->end(); + } +} bool BLEDevice::connected() const { diff --git a/libraries/CurieBLE/src/internal/BLEDeviceManager.cpp b/libraries/CurieBLE/src/internal/BLEDeviceManager.cpp index 7b3276ce..d5ddd181 100644 --- a/libraries/CurieBLE/src/internal/BLEDeviceManager.cpp +++ b/libraries/CurieBLE/src/internal/BLEDeviceManager.cpp @@ -81,7 +81,7 @@ BLEDeviceManager::BLEDeviceManager(): memset(_peer_adv_data, 0, sizeof(_peer_adv_data)); memset(_peer_adv_data_len, 0, sizeof(_peer_adv_data_len)); memset(_peer_scan_rsp_data, 0, sizeof(_peer_scan_rsp_data)); - memset(_peer_scan_rsp_data_len, 0, sizeof(_peer_scan_rsp_data_len)); + memset(_peer_scan_rsp_data_len, -1, sizeof(_peer_scan_rsp_data_len)); memset(_peer_adv_rssi, 0, sizeof(_peer_adv_rssi)); memset(_peer_adv_connectable, 0, sizeof(_peer_adv_connectable)); @@ -167,6 +167,10 @@ void BLEDeviceManager::poll() void BLEDeviceManager::end() { + stopScanning(); + stopAdvertising(); + // Disconnect the connections + disconnect(&BLE); } bool BLEDeviceManager::connected(const BLEDevice *device) const @@ -1384,7 +1388,7 @@ BLEDevice BLEDeviceManager::available() { uint64_t timestamp_delta = timestamp - _peer_adv_mill[i]; temp = &_peer_adv_buffer[i]; - if ((timestamp_delta <= 2000) && (max_delta < timestamp_delta)) + if ((timestamp_delta <= 2000) && (max_delta < timestamp_delta) && (_peer_scan_rsp_data_len[i] >= 0 || !_peer_adv_connectable[i])) { // Eable the duplicate filter if (_adv_duplicate_filter_enabled && @@ -1446,7 +1450,7 @@ bool BLEDeviceManager::setAdvertiseBuffer(const bt_addr_le_t* bt_addr, if (max_delta > 2000) // expired { index = i; - _peer_scan_rsp_data_len[index] = 0; // Invalid the scan response + _peer_scan_rsp_data_len[index] = -1; // Invalid the scan response } } diff --git a/libraries/CurieBLE/src/internal/BLEDeviceManager.h b/libraries/CurieBLE/src/internal/BLEDeviceManager.h index 38930eb4..60aa6f17 100644 --- a/libraries/CurieBLE/src/internal/BLEDeviceManager.h +++ b/libraries/CurieBLE/src/internal/BLEDeviceManager.h @@ -392,7 +392,7 @@ class BLEDeviceManager uint8_t _peer_adv_data[BLE_MAX_ADV_BUFFER_CFG][BLE_MAX_ADV_SIZE]; uint8_t _peer_adv_data_len[BLE_MAX_ADV_BUFFER_CFG]; uint8_t _peer_scan_rsp_data[BLE_MAX_ADV_BUFFER_CFG][BLE_MAX_ADV_SIZE]; - uint8_t _peer_scan_rsp_data_len[BLE_MAX_ADV_BUFFER_CFG]; + int8_t _peer_scan_rsp_data_len[BLE_MAX_ADV_BUFFER_CFG]; int8_t _peer_adv_rssi[BLE_MAX_ADV_BUFFER_CFG]; bool _peer_adv_connectable[BLE_MAX_ADV_BUFFER_CFG]; diff --git a/libraries/CurieI2S/examples/I2SDMA_TXCallBack/I2SDMA_TXCallBack.ino b/libraries/CurieI2S/examples/I2SDMA_TXCallBack/I2SDMA_TXCallBack.ino index 8cfc478e..52b8de4c 100644 --- a/libraries/CurieI2S/examples/I2SDMA_TXCallBack/I2SDMA_TXCallBack.ino +++ b/libraries/CurieI2S/examples/I2SDMA_TXCallBack/I2SDMA_TXCallBack.ino @@ -10,7 +10,7 @@ #include const int BUFF_SIZE=64; -boolean blinkState = true; // state of the LED +bool blinkState = true; // state of the LED uint32_t dataBuff[BUFF_SIZE]; uint32_t loop_count = 0; void setup() diff --git a/libraries/CurieIMU/examples/FreeFallDetect/FreeFallDetect.ino b/libraries/CurieIMU/examples/FreeFallDetect/FreeFallDetect.ino index ca88e457..d964270a 100644 --- a/libraries/CurieIMU/examples/FreeFallDetect/FreeFallDetect.ino +++ b/libraries/CurieIMU/examples/FreeFallDetect/FreeFallDetect.ino @@ -10,7 +10,7 @@ #include "CurieIMU.h" -boolean blinkState = false; // state of the LED +bool blinkState = false; // state of the LED unsigned long loopTime = 0; // get the time since program started unsigned long interruptsTime = 0; // get the time when free fall event is detected diff --git a/libraries/CurieIMU/examples/MotionDetect/MotionDetect.ino b/libraries/CurieIMU/examples/MotionDetect/MotionDetect.ino index 400ad461..cb94d85a 100644 --- a/libraries/CurieIMU/examples/MotionDetect/MotionDetect.ino +++ b/libraries/CurieIMU/examples/MotionDetect/MotionDetect.ino @@ -10,7 +10,7 @@ #include "CurieIMU.h" -boolean blinkState = false; // state of the LED +bool blinkState = false; // state of the LED unsigned long loopTime = 0; // get the time since program started unsigned long interruptsTime = 0; // get the time when motion event is detected diff --git a/libraries/CurieIMU/examples/RawImuDataSerial/RawImuDataSerial.ino b/libraries/CurieIMU/examples/RawImuDataSerial/RawImuDataSerial.ino index d61da508..08eed73b 100644 --- a/libraries/CurieIMU/examples/RawImuDataSerial/RawImuDataSerial.ino +++ b/libraries/CurieIMU/examples/RawImuDataSerial/RawImuDataSerial.ino @@ -35,7 +35,7 @@ int ax, ay, az; // accelerometer values int gx, gy, gz; // gyrometer values const int ledPin = 13; // activity LED pin -boolean blinkState = false; // state of the LED +bool blinkState = false; // state of the LED int calibrateOffsets = 1; // int to determine whether calibration takes place or not diff --git a/libraries/CurieIMU/examples/ShockDetect/ShockDetect.ino b/libraries/CurieIMU/examples/ShockDetect/ShockDetect.ino index 467299a2..9f2d7a9e 100644 --- a/libraries/CurieIMU/examples/ShockDetect/ShockDetect.ino +++ b/libraries/CurieIMU/examples/ShockDetect/ShockDetect.ino @@ -10,7 +10,7 @@ #include "CurieIMU.h" -boolean blinkState = false; // state of the LED +bool blinkState = false; // state of the LED void setup() { Serial.begin(9600); // initialize Serial communication diff --git a/libraries/CurieIMU/examples/StepCount/StepCount.ino b/libraries/CurieIMU/examples/StepCount/StepCount.ino index aafc9483..9ebcadb0 100644 --- a/libraries/CurieIMU/examples/StepCount/StepCount.ino +++ b/libraries/CurieIMU/examples/StepCount/StepCount.ino @@ -20,9 +20,9 @@ */ const int ledPin = 13; -boolean stepEventsEnabeled = true; // whether you're polling or using events +bool stepEventsEnabeled = true; // whether you're polling or using events long lastStepCount = 0; // step count on previous polling check -boolean blinkState = false; // state of the LED +bool blinkState = false; // state of the LED void setup() { Serial.begin(9600); // initialize Serial communication diff --git a/libraries/CurieIMU/examples/ZeroMotionDetect/ZeroMotionDetect.ino b/libraries/CurieIMU/examples/ZeroMotionDetect/ZeroMotionDetect.ino index 56fc3a9d..1f7d11fe 100644 --- a/libraries/CurieIMU/examples/ZeroMotionDetect/ZeroMotionDetect.ino +++ b/libraries/CurieIMU/examples/ZeroMotionDetect/ZeroMotionDetect.ino @@ -9,7 +9,7 @@ */ #include "CurieIMU.h" -boolean ledState = false; // state of the LED +bool ledState = false; // state of the LED void setup() { Serial.begin(9600); // initialize Serial communication while(!Serial) ; // wait for serial port to connect. diff --git a/libraries/CurieIMU/keywords.txt b/libraries/CurieIMU/keywords.txt index 05b1cb2b..11bd0056 100644 --- a/libraries/CurieIMU/keywords.txt +++ b/libraries/CurieIMU/keywords.txt @@ -14,7 +14,7 @@ CurieIMUClass KEYWORD1 begin KEYWORD1 -dataReady KEYWORD1 +dataReady KEYWORD1 getGyroRate KEYWORD1 setGyroRate KEYWORD1 getAccelerometerRate KEYWORD1 @@ -65,7 +65,7 @@ readAcceleration KEYWORD1 readRotation KEYWORD1 readAccelerometer KEYWORD1 -readAccelerometerScaled KEYWORD1 +readAccelerometerScaled KEYWORD1 readGyro KEYWORD1 readGyroScaled KEYWORD1 readTemperature KEYWORD1 @@ -85,8 +85,8 @@ CurieIMU KEYWORD2 # Constants (LITERAL1) ####################################### -ACCEL LITERAL1 -GYRO LITERAL1 +ACCEL LITERAL1 +GYRO LITERAL1 X_AXIS LITERAL1 Y_AXIS LITERAL1 diff --git a/libraries/CurieIMU/src/CurieIMU.cpp b/libraries/CurieIMU/src/CurieIMU.cpp index e9e64760..2b2d5466 100644 --- a/libraries/CurieIMU/src/CurieIMU.cpp +++ b/libraries/CurieIMU/src/CurieIMU.cpp @@ -818,7 +818,7 @@ void CurieIMUClass::setTapDetectionThreshold(float threshold) case 16: default: - bmiThreshold = (threshold - 2500) / 500.0; + bmiThreshold = (threshold - 250) / 500.0; break; } diff --git a/libraries/CuriePowerManagement/README.md b/libraries/CuriePowerManagement/README.md new file mode 100644 index 00000000..8b472632 --- /dev/null +++ b/libraries/CuriePowerManagement/README.md @@ -0,0 +1,296 @@ +Table of Contents +================= + + * [CuriePower](#curiepower) + * [CuriePower API reference](#curiepower-api-reference) + * [Functions](#functions) + * [CuriePower.doze()](#curiepowerdoze) + * [CuriePower.doze(int duration)](#curiepowerdozeint-duration) + * [CuriePower.idle()](#curiepoweridle) + * [CuriePower.idle(int duration)](#curiepoweridleint-duration) + * [CuriePower.sleep()](#curiepowersleep) + * [CuriePower.sleep(int duration)](#curiepowersleepint-duration) + * [CuriePower.deepSleep()](#curiepowerdeepsleep) + * [CuriePower.deepSleep(int duration)](#curiepowerdeepsleepint-duration) + * [CuriePower.attachInterruptWakeup(uint32_t pin, voidFuncPtr callback, uint32_t mode)](#curiepowerattachinterruptwakeupuint32_t-pin-voidfuncptr-callback-uint32_t-mode) + * [CuriePower.detachInterruptWakeup(uint32_t pin)](#curiepowerdetachinterruptwakeupuint32_t-pin) + * [Tutorials](#tutorials) + * [Tutorial #1: TimedWakeup Example](#tutorial-1-timedwakeup-example) + * [Tutorial #2: WakeFromIMU Example](#tutorial-2-wakefromimu-example) + +# CuriePower +CuriePower is a Power Management library for Curie based boards such as the Arduino101/Genuino101 and tinyTILE + +# CuriePower API reference + +## Functions + +### ``CuriePower.doze()`` + +``` +void CuriePower.doze() +``` + +Places the SoC in "doze" mode which switches the system clock to the internal 32.768 kHz RTC oscillator. + +*Parameters* + +none + +*Return value* + +none + +### ``CuriePower.doze(int duration)`` + +``` +void CuriePower.doze(int duration) +``` + + +Places the SoC in "doze" mode which switches the system clock to the internal 32.768 kHz RTC oscillator for `duration` milliseconds + + +*Parameters* + +1. `int duration` : number in milliseconds to doze + +*Return value* + +none + +### ``CuriePower.idle()`` + +``` +void CuriePower.idle() +``` + +Places the SoC into "doze" mode then enters an infinite loop, effectively stopping all operations until a wake interrupt is generated. + +*Parameters* + +none + +*Return value* + +none + +### ``CuriePower.idle(int duration)`` + +``` +void CuriePower.idle(int duration) +``` + + +Places the SoC in "doze" mode and enters an infinite loop for `duration` milliseconds + + +*Parameters* + +1. `int duration` : number in milliseconds to idle + +*Return value* + +none + +### ``CuriePower.sleep()`` + +``` +void CuriePower.sleep() +``` + +Places the SoC into a sleep state, stopping all operations, until a wake interrupt is generated + +*Parameters* + +none + +*Return value* + +none + +### ``CuriePower.sleep(int duration)`` + +``` +void CuriePower.sleep(int duration) +``` + + +Places the SoC into a sleep state for `duration` milliseconds + + +*Parameters* + +1. `int duration` : number in milliseconds to sleep + +*Return value* + +none + +### ``CuriePower.deepSleep()`` + +``` +void CuriePower.deepSleep() +``` + +Places the SoC into a deep sleep state, stopping all operations, until a wake interrupt is generated + +*Parameters* + +none + +*Return value* + +none + +### ``CuriePower.deepSleep(int duration)`` + +``` +void CuriePower.deepSleep(int duration) +``` + + +Places the SoC into a deep sleep state for `duration` milliseconds + + +*Parameters* + +1. `int duration` : number in milliseconds to deep sleep + +*Return value* + +none + +### ``CuriePower.attachInterruptWakeup(uint32_t pin, voidFuncPtr callback, uint32_t mode)`` + +``` +void CuriePower.attachInterruptWakeup(uint32_t pin, voidFuncPtr callback, uint32_t mode) +``` + +Attaches a wakeup interrupt to digital pin `pin`. `callback` is the function to be called when the wakeup interrupt occurs. + +*Parameters* + +none + +*Return value* + +none + +### ``CuriePower.detachInterruptWakeup(uint32_t pin)`` + +``` +void CuriePower.detachInterruptWakeup(uint32_t pin) +``` + +Removes any wakeup interrupt attached to digital pin `pin`. + +*Parameters* + +none + +*Return value* + +none + +# Tutorials + +## Tutorial #1: TimedWakeup Example + +This sketch demonstrates the simplest way to use the CuriePower library. It blinks the LED a few times, goes to sleep for a certain amount of time then goes back at the start of loop() + +```cpp +#include + +void setup() { + pinMode(LED_BUILTIN, OUTPUT); +} + +void loop() { + for(int i = 0; i < 5; i++) + { + digitalWrite(LED_BUILTIN, HIGH); + delay(100); + digitalWrite(LED_BUILTIN, LOW); + delay(100); + } + PM.sleep(1000); +} +``` + +The line of code that is most interesting here is: +```cpp +PM.sleep(1000); +``` +This puts the SoC into sleep, drawing significantly less power, for 1000ms or 1s. + +In what situations is this most useful? + +Let's says you have a battery powered project that reads a sensor value once every second and saves it to an SD card. +Simply using delay() will work but you will notice that you will run out of battery pretty fast. That is because even though the code is not doing much inside delay, it is still running everything at full clock speed and all peripherals are turned on. +When we put the SoC to sleep, several things are turned off. This includes most of the peripherals. voltage rails, and some clocks. Basically, it draws much less power and no code is running until a wake interrupt is generated. + +Many Arduino projects typically have a loop where you read a sensor, do something with that reading, and then delay for a set amount of time. +In most cases, reading the sensor and doing something with that reading takes very little time, much smaller than the delay duration. This means that we are wasting a lot of power inside the delay doing nothing. +By placing the SoC to sleep instead of just waiting inside the delay, we can save a considerable amount of power in most applications. + + +## Tutorial #2: WakeFromIMU Example + +This sketch uses CuriePower library and the CurieIMU library together and demonstrates the use of an interrupt to wake the Curie SoC from sleep. + +```cpp +#include +#include "CurieIMU.h" + + +void setup() { + pinMode(LED_BUILTIN, OUTPUT); + CurieIMU.begin(); + CurieIMU.attachInterrupt(wakeup); + CurieIMU.setDetectionThreshold(CURIE_IMU_MOTION, 20); // 100mg + CurieIMU.setDetectionDuration(CURIE_IMU_MOTION, 10); // trigger times of consecutive slope data points + CurieIMU.interrupts(CURIE_IMU_MOTION); + +} + +void loop() { + PM.sleep(); + digitalWrite(LED_BUILTIN, HIGH); + delay(3000); + digitalWrite(LED_BUILTIN, LOW); +} + +void wakeup() +{ + PM.wakeFromDoze(); + // This function will be called once on device wakeup + // You can do some little operations here (like changing variables which will be used in the loop) + // Remember to avoid calling delay() and long running functions since this functions executes in interrupt context +} +``` + +If you look at the beginning of loop() you will see: +```cpp +PM.sleep(); +``` +This line of code puts the SoC into a sleep state. The SoC will remain in a sleep state until it is woken by an interrupt. +If no interrupt triggers the SoC to wake up, it will stay in a sleep state forever(or until the battery runs out). +This is specifically useful in applications that are not periodic, like in this example sketch where the SoC stays at a sleep state until the Arduino101 detects motion, or more precisely the Bosch BMI160 [6-Axis Accelerometer/Gyroscope] sensor detects the motion and triggers an interrupt to wake the Curie Soc from sleep. + +Inside setup() we have: +```cpp +CurieIMU.attachInterrupt(wakeup); +CurieIMU.setDetectionThreshold(CURIE_IMU_MOTION, 20); // 100mg +CurieIMU.setDetectionDuration(CURIE_IMU_MOTION, 10); // trigger times of consecutive slope data points +CurieIMU.interrupts(CURIE_IMU_MOTION); +``` +These lines of code attaches a method called wakeup() which is called whenever motion is detected. Since the interrupt signal generated by the Bosch BMI160 sensor is already internally connected to AON(Always On) interrupt of the SoC, it automatically wakes the SoC from sleep. +However, since we are using the attachInterrupt() method of the CurieIMU Library instead of the one from the CuriePower Library we still need to do one more thing after the SoC is taken out of a sleep state. + +Inside the wakeup() method: +```cpp +PM.wakeFromDoze(); +``` +This line of code simply takes the SoC out of the Doze state, switching it from using the internal RTC 32.768 KHz as the main clock, back to the 32Mhz oscillator. +At this point the SoC runs back at full speed ready to do stuff quickly and then go back to sleep to save power. diff --git a/libraries/CuriePowerManagement/examples/TimedWakeup/TimedWakeup.ino b/libraries/CuriePowerManagement/examples/TimedWakeup/TimedWakeup.ino new file mode 100644 index 00000000..baeb4dec --- /dev/null +++ b/libraries/CuriePowerManagement/examples/TimedWakeup/TimedWakeup.ino @@ -0,0 +1,16 @@ +#include + +void setup() { + pinMode(LED_BUILTIN, OUTPUT); +} + +void loop() { + for(int i = 0; i < 5; i++) + { + digitalWrite(LED_BUILTIN, HIGH); + delay(100); + digitalWrite(LED_BUILTIN, LOW); + delay(100); + } + PM.sleep(1000); +} \ No newline at end of file diff --git a/libraries/CuriePowerManagement/examples/WakeFromIMU/WakeFromIMU.ino b/libraries/CuriePowerManagement/examples/WakeFromIMU/WakeFromIMU.ino new file mode 100644 index 00000000..7cf2015c --- /dev/null +++ b/libraries/CuriePowerManagement/examples/WakeFromIMU/WakeFromIMU.ino @@ -0,0 +1,28 @@ +#include +#include "CurieIMU.h" + + +void setup() { + pinMode(LED_BUILTIN, OUTPUT); + CurieIMU.begin(); + CurieIMU.attachInterrupt(wakeup); + CurieIMU.setDetectionThreshold(CURIE_IMU_MOTION, 20); // 100mg + CurieIMU.setDetectionDuration(CURIE_IMU_MOTION, 10); // trigger times of consecutive slope data points + CurieIMU.interrupts(CURIE_IMU_MOTION); + +} + +void loop() { + PM.sleep(); + digitalWrite(LED_BUILTIN, HIGH); + delay(3000); + digitalWrite(LED_BUILTIN, LOW); +} + +void wakeup() +{ + PM.wakeFromDoze(); + // This function will be called once on device wakeup + // You can do some little operations here (like changing variables which will be used in the loop) + // Remember to avoid calling delay() and long running functions since this functions executes in interrupt context +} diff --git a/libraries/CuriePowerManagement/keywords.txt b/libraries/CuriePowerManagement/keywords.txt new file mode 100644 index 00000000..7051dfac --- /dev/null +++ b/libraries/CuriePowerManagement/keywords.txt @@ -0,0 +1,24 @@ +####################################### +# Syntax Coloring Map For Curie Power Library +####################################### + +####################################### +# Datatypes (KEYWORD1) +####################################### + +####################################### +# Methods and Functions (KEYWORD2) +####################################### +sleep KEYWORD2 +deepSleep KEYWORD2 +idle KEYWORD2 +doze KEYWORD2 +wakeFromDoze KEYWORD2 + +####################################### +# Instances (KEYWORD2) +####################################### + +####################################### +# Constants (LITERAL1) +####################################### diff --git a/libraries/CuriePowerManagement/library.properties b/libraries/CuriePowerManagement/library.properties new file mode 100644 index 00000000..83a2661e --- /dev/null +++ b/libraries/CuriePowerManagement/library.properties @@ -0,0 +1,9 @@ +name=CuriePowerManagement +version=1.0 +author=Intel +maintainer=Intel +sentence=Curie Power Management library for Curie based boards. +paragraph=Allows to manage the power states of Curie based boards. +category=Device Control +url= +architectures=arc32 diff --git a/libraries/CuriePowerManagement/src/Power.cpp b/libraries/CuriePowerManagement/src/Power.cpp new file mode 100644 index 00000000..450c2ad7 --- /dev/null +++ b/libraries/CuriePowerManagement/src/Power.cpp @@ -0,0 +1,478 @@ +#include "Power.h" + +Power PM; +uint32_t arc_restore_addr; +uint32_t cpu_context[33]; + +typedef void (*user_cb)(void); + +static void sleepInterruptHandler(void) +{ + unsigned int flags = interrupt_lock(); + PM.wakeFromDoze(); + PM.wakeFromSleepCallback(); + interrupt_unlock(flags); +} + +static void dozeInterruptHandler(void) +{ + unsigned int flags = interrupt_lock(); + PM.wakeFromDoze(); + interrupt_unlock(flags); +} + +static void soc_gpio_sleep_isr() +{ + if(soc_sleeping || soc_dozing) + { + unsigned int flags = interrupt_lock(); + PM.wakeFromDoze(); + wsrc_t wsrc; + while (wsrc_get_newest_attached(&wsrc)){ + PinDescription *p = &g_APinDescription[wsrc.id]; + uint32_t mask = 0x1 << p->ulGPIOId; + if(p->ulGPIOPort == SOC_GPIO_32){ + uint32_t status = shared_data->pm_int_status; + if((status>>p->ulGPIOId)&0x1){ + //call user callback + user_cb cb = (user_cb)wsrc.callback; + cb(); + } + } + } + interrupt_unlock(flags); + } + soc_sleeping = false; +} + +static void soc_aongpio_sleep_isr() +{ + if(soc_sleeping || soc_dozing){ + unsigned int flags = interrupt_lock(); + PM.wakeFromDoze(); + wsrc_t wsrc; + while (wsrc_get_newest_attached(&wsrc)){ + PinDescription *p = &g_APinDescription[wsrc.id]; + uint32_t mask = 0x1 << p->ulGPIOId; + if(p->ulGPIOPort == SOC_GPIO_32){ + // Save interrupt status + uint32_t status = MMIO_REG_VAL_FROM_BASE(SOC_GPIO_AON_BASE_ADDR, SOC_GPIO_INTSTATUS); + // Mask the pending interrupts + MMIO_REG_VAL_FROM_BASE(SOC_GPIO_AON_BASE_ADDR, SOC_GPIO_INTMASK) |= status; + shared_data->pm_int_status = status; + // Clear interrupt flag (write 1 to clear) + MMIO_REG_VAL_FROM_BASE(SOC_GPIO_AON_BASE_ADDR, SOC_GPIO_PORTA_EOI) = status; + if((status>>p->ulGPIOId)&0x1){ + //call user callback + user_cb cb = (user_cb)wsrc.callback; + cb(); + } + } + } + interrupt_unlock(flags); + } + soc_sleeping = false; +} + +static void ss_gpio0_sleep_isr() +{ + if(soc_sleeping || soc_dozing){ + unsigned int flags = interrupt_lock(); + PM.wakeFromDoze(); + wsrc_t wsrc; + while (wsrc_get_newest_attached(&wsrc)) { + PinDescription *p = &g_APinDescription[wsrc.id]; + uint32_t mask = 0x1 << p->ulGPIOId; + if(p->ulGPIOPort == SS_GPIO_8B0){ + uint32_t status = shared_data->pm_int_status; + if((status>>p->ulGPIOId)&0x1){ + //call user callback + user_cb cb = (user_cb)wsrc.callback; + cb(); + } + } + } + interrupt_unlock(flags); + } + soc_sleeping = false; +} + +static void ss_gpio1_sleep_isr() +{ + if(soc_sleeping || soc_dozing){ + unsigned int flags = interrupt_lock(); + PM.wakeFromDoze(); + wsrc_t wsrc; + while (wsrc_get_newest_attached(&wsrc)) { + PinDescription *p = &g_APinDescription[wsrc.id]; + uint32_t mask = 0x1 << p->ulGPIOId; + if(p->ulGPIOPort == SS_GPIO_8B1){ + uint32_t status = shared_data->pm_int_status; + if((status>>p->ulGPIOId)&0x1){ + //call user callback + user_cb cb = (user_cb)wsrc.callback; + cb(); + } + } + } + interrupt_unlock(flags); + } + soc_sleeping = false; +} + +static void aontimer_isr() +{ + if(soc_sleeping || soc_dozing){ + unsigned int flags = interrupt_lock(); + interrupt_disable(IRQ_ALWAYS_ON_TMR); + *AONPT_CFG = 0; + PM.wakeFromDoze(); + interrupt_unlock(flags); + //wait until quark core is running + volatile uint32_t psts = (MMIO_REG_VAL(P_STS))&0x7; + while(psts){ + psts = (MMIO_REG_VAL(P_STS))&0x7; + } + PM.wakeFromSleepCallback(); + } + soc_sleeping = false; +} + +Power::Power() +{ + +} + +void Power::doze() +{ + //actually attach the interrupts + enableWakeInterrupts(); + turnOffUSB(); + soc_dozing = true; + //switch from external crystal oscillator to internal hybrid oscillator + switchToHybridOscillator(); + + //Set system clock to the RTC Crystal Oscillator + uint32_t current_val = MMIO_REG_VAL(CCU_SYS_CLK_CTL); + MMIO_REG_VAL(CCU_SYS_CLK_CTL) = current_val & 0xFFFFFFFE; + + //Powerdown hybrid oscillator + current_val = MMIO_REG_VAL(OSC0_CFG1); + MMIO_REG_VAL(OSC0_CFG1) = current_val | 0x00000004; +} + +void Power::doze(int duration) +{ + doze(); + delayTicks(millisToRTCTicks(duration)); + wakeFromDoze(); +} + +void Power::idle() +{ + doze(); + while(soc_dozing); +} + +void Power::idle(int duration) +{ + enableAONPTimerInterrrupt(duration); + idle(); +} + +void Power::wakeFromDoze() +{ + //Powerup hybrid oscillator + uint32_t current_val = MMIO_REG_VAL(OSC0_CFG1); + MMIO_REG_VAL(OSC0_CFG1) = current_val & 0xFFFFFFFB; + + //Set system clock to the Hybrid Oscillator + current_val = MMIO_REG_VAL(CCU_SYS_CLK_CTL); + MMIO_REG_VAL(CCU_SYS_CLK_CTL) = current_val | 0x00000001; + + //switch back to the external crystal oscillator + void switchToCrystalOscillator(); + + turnOnUSB(); + soc_dozing = false; +} + +void Power::sleep() +{ + soc_sleeping = true; + //disable low power mode on OPM_2P6 regulator + MMIO_REG_VAL(SLP_CFG) &= ~(1 << LPMODE_EN); + + uint32_t creg_mst0_ctrl = 0; + creg_mst0_ctrl = READ_ARC_REG(QM_SS_CREG_BASE); + + /* + * Clock gate the sensor peripherals at CREG level. + * This clock gating is independent of the peripheral-specific clock + * gating provided in ss_clk.h . + */ + creg_mst0_ctrl |= (QM_SS_IO_CREG_MST0_CTRL_ADC_CLK_GATE | + QM_SS_IO_CREG_MST0_CTRL_I2C1_CLK_GATE | + QM_SS_IO_CREG_MST0_CTRL_I2C0_CLK_GATE | + QM_SS_IO_CREG_MST0_CTRL_SPI1_CLK_GATE | + QM_SS_IO_CREG_MST0_CTRL_SPI0_CLK_GATE); + + WRITE_ARC_REG(creg_mst0_ctrl, QM_SS_CREG_BASE); + + //Send request to put quark core to sleep + //x86_C2LPRequest(); //can only wake Quark core using AON_GPIO, RTC, AON_Timer, and AON_Comparators + x86_C2Request(); + doze(); + + __asm__ __volatile__( + "sleep %0" + : + : "i"(QM_SS_SLEEP_MODE_CORE_TIMERS_RTC_OFF)); + + creg_mst0_ctrl &= ~(QM_SS_IO_CREG_MST0_CTRL_ADC_CLK_GATE | + QM_SS_IO_CREG_MST0_CTRL_I2C1_CLK_GATE | + QM_SS_IO_CREG_MST0_CTRL_I2C0_CLK_GATE | + QM_SS_IO_CREG_MST0_CTRL_SPI1_CLK_GATE | + QM_SS_IO_CREG_MST0_CTRL_SPI0_CLK_GATE); + + WRITE_ARC_REG(creg_mst0_ctrl, QM_SS_CREG_BASE); + soc_sleeping = false; +} + +void Power::sleep(int duration) +{ + enableAONPTimerInterrrupt(duration); + sleep(); +} + +void Power::deepSleep() +{ + sleep(); +} + +void Power::deepSleep(int duration) +{ + sleep(duration); +} + +inline void Power::wakeFromSleepCallback(void) +{ + //ToDo: check table and call apprpriate CBs + if(pmCB != NULL) + pmCB(); + //ToDo: unregister all sleep IRQs +} + +inline void Power::wakeFromDozeCallback(void) +{ + //ToDo: check table and call apprpriate CBs + if(pmCB != NULL) + pmCB(); +} + +void Power::attachInterruptWakeup(uint32_t pin, voidFuncPtr callback, uint32_t mode) +{ + if (pin > NUM_WAKEUP) { + return; + } + + if (pin <= GPIO_END) { + wsrc_register_gpio(pin, callback, mode); + } + else{ + wsrc_register_id(pin, callback); + } +} + +void Power::detachInterruptWakeup(uint32_t pin) +{ + wsrc_unregister(pin); + if (pin <= GPIO_END) { + detachInterrupt(pin); + } +} + +//Privates + +void Power::turnOffUSB() +{ + MMIO_REG_VAL(USB_PHY_CFG0) |= 0x00000001; +} + +void Power::turnOnUSB() +{ + MMIO_REG_VAL(USB_PHY_CFG0) &= 0xFFFFFFFE; +} + +void Power::switchToHybridOscillator() +{ + //read trim value from OTP + uint32_t trimMask = *(uint16_t*)OSCTRIM_ADDR << 20; + MMIO_REG_VAL(OSC0_CFG1) = 0x00000002 | trimMask; //switch to internal hybrid oscillator using trim value from OTP + //ToDo: wait for hybrid oscillator to stabilize +} + +void Power::switchToCrystalOscillator() +{ + MMIO_REG_VAL(OSC0_CFG1) = 0x00070009; + while(!(MMIO_REG_VAL(OSC0_STAT) & 0x00000002)); //wait till crystal oscillator is stable +} + +void Power::setRTCCMR(int seconds) +{ + MMIO_REG_VAL(RTC_CMR) = readRTC_CCVR() + seconds; +} + +uint32_t Power::readRTC_CCVR() +{ + return *RTC_CCVR; +} + +uint32_t Power::millisToRTCTicks(int milliseconds) +{ + return (uint32_t)((double)milliseconds*32.768); +} + +void Power::enableRTCInterrupt(int seconds) +{ + setRTCCMR(seconds); + MMIO_REG_VAL(RTC_MASK_INT) &= 0xFFFFFEFE; + MMIO_REG_VAL(RTC_CCR) |= 0x00000001; + MMIO_REG_VAL(RTC_CCR) &= 0xFFFFFFFD; + volatile uint32_t read = MMIO_REG_VAL(RTC_EOI); + + pmCB = &wakeFromRTC; + interrupt_disable(IRQ_RTC_INTR); + interrupt_connect(IRQ_RTC_INTR , &sleepInterruptHandler); + delayTicks(6400); //2ms + interrupt_enable(IRQ_RTC_INTR); +} + +void Power::enableAONGPIOInterrupt(int aon_gpio, int mode) +{ + switch(mode){ + case CHANGE: //not supported just do the same as FALLING + MMIO_REG_VAL(AON_GPIO_INTTYPE_LEVEL) |= 1 << aon_gpio; + MMIO_REG_VAL(AON_GPIO_INT_POL) &= ~(1 << aon_gpio); + break; + case RISING: + MMIO_REG_VAL(AON_GPIO_INTTYPE_LEVEL) |= 1 << aon_gpio; + MMIO_REG_VAL(AON_GPIO_INT_POL) |= 1 << aon_gpio; + break; + case FALLING: + MMIO_REG_VAL(AON_GPIO_INTTYPE_LEVEL) |= 1 << aon_gpio; + MMIO_REG_VAL(AON_GPIO_INT_POL) &= ~(1 << aon_gpio); + break; + case HIGH: + MMIO_REG_VAL(AON_GPIO_INTTYPE_LEVEL) &= ~(1 << aon_gpio); + MMIO_REG_VAL(AON_GPIO_INT_POL) |= 1 << aon_gpio; + break; + case LOW: + MMIO_REG_VAL(AON_GPIO_INTTYPE_LEVEL) &= ~(1 << aon_gpio); + MMIO_REG_VAL(AON_GPIO_INT_POL) &= ~(1 << aon_gpio); + break; + default: + MMIO_REG_VAL(AON_GPIO_INTTYPE_LEVEL) &= ~(1 << aon_gpio); + MMIO_REG_VAL(AON_GPIO_INT_POL) &= ~(1 << aon_gpio); + break; + }; + + MMIO_REG_VAL(AON_GPIO_SWPORTA_DDR) &= ~(1 << aon_gpio); + MMIO_REG_VAL(AON_GPIO_INTMASK) &= ~(1 << aon_gpio); + MMIO_REG_VAL(AON_GPIO_INTEN) |= 1 << aon_gpio; + + *AON_GPIO_MASK_INT &= 0xFFFFFEFE; + interrupt_disable(IRQ_ALWAYS_ON_GPIO); + interrupt_connect(IRQ_ALWAYS_ON_GPIO , &soc_aongpio_sleep_isr); + interrupt_enable(IRQ_ALWAYS_ON_GPIO); +} + +void Power::enableAONPTimerInterrrupt(int millis) +{ + WRITE_ARC_REG(QM_IRQ_AONPT_0_INT_VECTOR, QM_SS_AUX_IRQ_SELECT); + WRITE_ARC_REG(QM_SS_IRQ_LEVEL_SENSITIVE, QM_SS_AUX_IRQ_TRIGGER); + + interrupt_disable(IRQ_ALWAYS_ON_TMR); + pmCB = resetAONPTimer; + *AONPT_CFG = millisToRTCTicks(millis); + interrupt_connect(IRQ_ALWAYS_ON_TMR , &aontimer_isr); + *AON_TIMER_MASK_INT &= 0xFFFFFEFE; + *AONPT_CTRL |= 0x00000002; + *AONPT_CTRL |= 0x00000001; + volatile uint32_t aonpt_stat = *AONPT_STAT; + while(aonpt_stat){ + *AONPT_CTRL &= 0xFFFFFFFE; + *AONPT_CTRL |= 0x00000001; + aonpt_stat = *AONPT_STAT; + //delayTicks(1000); + } + interrupt_enable(IRQ_ALWAYS_ON_TMR); +} + +void Power::enableWakeInterrupts() +{ + void (*fptr)(void); + wsrc_t wsrc; + + while (wsrc_get_newest_attached(&wsrc)) { + switch(wsrc.irq){ + case IRQ_ALWAYS_ON_GPIO: + enableAONGPIOInterrupt((wsrc.id-GPIO_END), wsrc_gpio_mode(wsrc.status)); + break; + case IRQ_ALWAYS_ON_TMR: + break; + case IRQ_RTC_INTR: + break; + case IRQ_GPIO0_INTR: + attachInterrupt(wsrc.id, &ss_gpio0_sleep_isr, wsrc_gpio_mode(wsrc.status)); + interrupt_enable(wsrc.irq); + break; + case IRQ_GPIO1_INTR: + attachInterrupt(wsrc.id, &ss_gpio1_sleep_isr, wsrc_gpio_mode(wsrc.status)); + interrupt_enable(wsrc.irq); + break; + case IRQ_GPIO_INTR: + attachInterrupt(wsrc.id, &soc_gpio_sleep_isr, wsrc_gpio_mode(wsrc.status)); + interrupt_enable(wsrc.irq); + break; + case IRQ_TIMER1: + break; + default: + break; + } + } +} + +void Power::resetAONPTimer() +{ + interrupt_disable(IRQ_ALWAYS_ON_TMR); + *AON_TIMER_MASK_INT |= 0xFFFFF1F1; + *AONPT_CFG = 0; + *AONPT_CTRL |= 0x00000001; + WRITE_ARC_REG(QM_IRQ_AONPT_0_INT_VECTOR, QM_SS_AUX_IRQ_SELECT); + WRITE_ARC_REG(QM_SS_IRQ_EDGE_SENSITIVE, QM_SS_AUX_IRQ_TRIGGER); +} + +void Power::wakeFromRTC() +{ + MMIO_REG_VAL(RTC_MASK_INT) |= 0x00000101; + interrupt_disable(IRQ_RTC_INTR); + volatile uint32_t read = MMIO_REG_VAL(RTC_EOI); +} + +void Power::x86_C2Request() +{ + switchToHybridOscillator(); + //request for the x86 core go into C2 sleep + MMIO_REG_VAL(CCU_LP_CLK_CTL) &= 0xFFFFFFFC; + volatile uint32_t c2 = MMIO_REG_VAL(P_LVL2); +} + +void Power::x86_C2LPRequest() +{ + switchToHybridOscillator(); + //request for the x86 core go into C2LP sleep + MMIO_REG_VAL(CCU_LP_CLK_CTL) &= 0xFFFFFFFE; + MMIO_REG_VAL(CCU_LP_CLK_CTL) |= 0x00000002; + volatile uint32_t c2lp = MMIO_REG_VAL(P_LVL2); +} diff --git a/libraries/CuriePowerManagement/src/Power.h b/libraries/CuriePowerManagement/src/Power.h new file mode 100644 index 00000000..dfd919b6 --- /dev/null +++ b/libraries/CuriePowerManagement/src/Power.h @@ -0,0 +1,133 @@ +#define OSC0_STAT 0xB0800004 +#define OSC0_CFG1 0xB0800008 + +#define CCU_SS_PERIPH_CLK_GATE_CTL 0xB0800028 +#define CCU_LP_CLK_CTL 0xB080002C +#define CCU_SYS_CLK_CTL 0xB0800038 +#define P_LVL2 0xB0800504 +#define PM1C 0xB0800518 +#define SLP_CFG 0xB0800550 +#define SS_STS 0xB0800604 + +#define AONC_CNT 0xB0800700 +#define AONC_CFG 0xB0800704 +#define AONPT_CNT 0xB0800708 +#define AONPT_STAT (volatile int*)0xB080070C +#define AONPT_CTRL (volatile int*)0xB0800710 +#define AONPT_CFG (volatile int*)0xB0800714 + +#define USB_PLL_CFG0 0xB0800014 +#define USB_PHY_CFG0 0xB0800800 + +#define RTC_CCVR (volatile int*)0xB0000400 // Current Counter Value Register +#define RTC_CMR 0xB0000404 +#define RTC_CCR 0xB000040C +#define RTC_EOI 0xB0000418 + +#define RTC_MASK_INT 0xB0800478 +#define AON_TIMER_MASK_INT (volatile int*)0xB08004C8 +#define AON_GPIO_MASK_INT (volatile int*)0xB08004D4 + +#define AON_GPIO_SWPORTA_DR 0xB0800B00 +#define AON_GPIO_SWPORTA_DDR 0xB0800B04 +#define AON_GPIO_SWPORTA_CTL 0xB0800B08 +#define AON_GPIO_INTEN 0xB0800B30 +#define AON_GPIO_INTMASK 0xB0800B34 +#define AON_GPIO_INTTYPE_LEVEL 0xB0800B38 +#define AON_GPIO_INT_POL 0xB0800B3C +#define AON_GPIO_DEBOUNCE 0xB0888B48 +#define AON_GPIO_PORTA_EOI 0xB0800B4C + +#define OSCTRIM_ADDR 0xffffe1f8 + +#define QM_SS_SLEEP_MODE_CORE_OFF (0x0) +#define QM_SS_SLEEP_MODE_CORE_OFF_TIMER_OFF (0x20) +#define QM_SS_SLEEP_MODE_CORE_TIMERS_RTC_OFF (0x60) + +#define P_STS 0xB0800560 + +#define LPMODE_EN 8 + +#include +#include +#include +#include +#include +#include "qmsi/qm_sensor_regs.h" +#include "qmsi/ss_power_states.h" +#include "wsrc.h" + +static volatile bool soc_sleeping = false; +static volatile bool soc_dozing = false; + +class Power +{ + public: + Power(); + + //puts the SoC into "doze" mode which lowers the system clock speed to 32k + void doze(); + + void doze(int duration); + + void idle(); + + void idle(int duration); + + void wakeFromDoze(); + + void sleep(); + + void sleep(int duration); + + void deepSleep(); + + void deepSleep(int duration); + + void wakeFromSleepCallback(void); + + void wakeFromDozeCallback(void); + + void attachInterruptWakeup(uint32_t pin, voidFuncPtr callback, uint32_t mode); + + void detachInterruptWakeup(uint32_t pin); + + uint32_t arc_restore_addr; + + private: + void turnOffUSB(); + + void turnOnUSB(); + + void switchToHybridOscillator(); + + void switchToCrystalOscillator(); + + void setRTCCMR(int seconds); + + uint32_t readRTC_CCVR(); + + bool isSleeping = false; + + uint32_t millisToRTCTicks(int milliseconds); + + void enableRTCInterrupt(int seconds); + + void enableAONGPIOInterrupt(int aon_gpio, int mode); + + void enableAONPTimerInterrrupt(int millis); + + void enableWakeInterrupts(); + + static void resetAONPTimer(); + + static void wakeFromRTC(); + + void x86_C2Request(); + + void x86_C2LPRequest(); + + void (*pmCB)(); +}; + +extern Power PM; diff --git a/libraries/CuriePowerManagement/src/qmsi/power_states.h b/libraries/CuriePowerManagement/src/qmsi/power_states.h new file mode 100644 index 00000000..eb5fecf0 --- /dev/null +++ b/libraries/CuriePowerManagement/src/qmsi/power_states.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2016, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __POWER_STATES_H__ +#define __POWER_STATES_H__ + +/** + * SoC Power mode control for Quark SE Microcontrollers. + * + * Available SoC states are: + * - Low Power Sensing Standby (LPSS) + * - Sleep + * + * LPSS can only be enabled from the Sensor core, + * refer to @ref ss_power_soc_lpss_enable for further details. + * + * @defgroup groupSoCPower Quark SE SoC Power states + * @{ + */ + +/** + * Enter SoC sleep state. + * + * Put the SoC into sleep state until next SoC wake event. + * + * - Core well is turned off + * - Always on well is on + * - Hybrid Clock is off + * - RTC Clock is on + * + * Possible SoC wake events are: + * - Low Power Comparator Interrupt + * - AON GPIO Interrupt + * - AON Timer Interrupt + * - RTC Interrupt + */ +void power_soc_sleep(void); + +/** + * Enter SoC deep sleep state. + * + * Put the SoC into deep sleep state until next SoC wake event. + * + * - Core well is turned off + * - Always on well is on + * - Hybrid Clock is off + * - RTC Clock is on + * + * Possible SoC wake events are: + * - Low Power Comparator Interrupt + * - AON GPIO Interrupt + * - AON Timer Interrupt + * - RTC Interrupt + * + * This function puts 1P8V regulators and 3P3V into Linear Mode. + */ +void power_soc_deep_sleep(void); + +/** + * @} + */ + +#endif /* __POWER_STATES_H__ */ diff --git a/libraries/CuriePowerManagement/src/qmsi/qm_interrupt_router_regs.h b/libraries/CuriePowerManagement/src/qmsi/qm_interrupt_router_regs.h new file mode 100644 index 00000000..216612e9 --- /dev/null +++ b/libraries/CuriePowerManagement/src/qmsi/qm_interrupt_router_regs.h @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2016, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __QM_INTERRUPT_ROUTER_REGS_H__ +#define __QM_INTERRUPT_ROUTER_REGS_H__ + +/** + * Quark SE SoC Event Router registers. + * + * @defgroup groupQUARKSESEEVENTROUTER SoC Event Router (SE) + * @{ + */ + +/** + * Masks for single source interrupts in the Event Router. + * To enable: reg &= ~(MASK) + * To disable: reg |= MASK; + */ +#define QM_IR_INT_LMT_MASK BIT(0) +#define QM_IR_INT_SS_MASK BIT(8) + +/* Masks for single source halts in the Event Router. */ +#define QM_IR_INT_LMT_HALT_MASK BIT(16) +#define QM_IR_INT_SS_HALT_MASK BIT(24) + +/* Event Router Unmask interrupts for a peripheral. */ +#define QM_IR_UNMASK_LMT_INTERRUPTS(_peripheral_) \ + (_peripheral_ &= ~(QM_IR_INT_LMT_MASK)) +#define QM_IR_UNMASK_SS_INTERRUPTS(_peripheral_) \ + (_peripheral_ &= ~(QM_IR_INT_SS_MASK)) + +/* Mask interrupts for a peripheral. */ +#define QM_IR_MASK_LMT_INTERRUPTS(_peripheral_) \ + (_peripheral_ |= QM_IR_INT_LMT_MASK) +#define QM_IR_MASK_SS_INTERRUPTS(_peripheral_) \ + (_peripheral_ |= QM_IR_INT_SS_MASK) + +/* Unmask halt for a peripheral. */ +#define QM_IR_UNMASK_LMT_HALTS(_peripheral_) \ + (_peripheral_ &= ~(QM_IR_INT_LMT_HALT_MASK)) +#define QM_IR_UNMASK_SS_HALTS(_peripheral_) \ + (_peripheral_ &= ~(QM_IR_INT_SS_HALT_MASK)) + +/* Mask halt for a peripheral. */ +#define QM_IR_MASK_LMT_HALTS(_peripheral_) \ + (_peripheral_ |= QM_IR_INT_LMT_HALT_MASK) +#define QM_IR_MASK_SS_HALTS(_peripheral_) \ + (_peripheral_ |= QM_IR_INT_SS_HALT_MASK) + +#define QM_IR_GET_LMT_MASK(_peripheral_) (_peripheral_ & QM_IR_INT_LMT_MASK) +#define QM_IR_GET_LMT_HALT_MASK(_peripheral_) \ + (_peripheral_ & QM_IR_INT_LMT_HALT_MASK) + +#define QM_IR_GET_SS_MASK(_peripheral_) (_peripheral_ & QM_IR_INT_SS_MASK) +#define QM_IR_GET_SS_HALT_MASK(_peripheral_) \ + (_peripheral_ & QM_IR_INT_SS_HALT_MASK) + +/* Define macros for use by the active core. */ +#if (QM_LAKEMONT) +#define QM_IR_UNMASK_INTERRUPTS(_peripheral_) \ + QM_IR_UNMASK_LMT_INTERRUPTS(_peripheral_) +#define QM_IR_MASK_INTERRUPTS(_peripheral_) \ + QM_IR_MASK_LMT_INTERRUPTS(_peripheral_) +#define QM_IR_UNMASK_HALTS(_peripheral_) QM_IR_UNMASK_LMT_HALTS(_peripheral_) +#define QM_IR_MASK_HALTS(_peripheral_) QM_IR_MASK_LMT_HALTS(_peripheral_) + +#define QM_IR_INT_MASK QM_IR_INT_LMT_MASK +#define QM_IR_INT_HALT_MASK QM_IR_INT_LMT_HALT_MASK +#define QM_IR_GET_MASK(_peripheral_) QM_IR_GET_LMT_MASK(_peripheral_) +#define QM_IR_GET_HALT_MASK(_peripheral_) QM_IR_GET_LMT_HALT_MASK(_peripheral_) + +#elif(QM_SENSOR) +#define QM_IR_UNMASK_INTERRUPTS(_peripheral_) \ + QM_IR_UNMASK_SS_INTERRUPTS(_peripheral_) +#define QM_IR_MASK_INTERRUPTS(_peripheral_) \ + QM_IR_MASK_SS_INTERRUPTS(_peripheral_) +#define QM_IR_UNMASK_HALTS(_peripheral_) QM_IR_UNMASK_SS_HALTS(_peripheral_) +#define QM_IR_MASK_HALTS(_peripheral_) QM_IR_MASK_SS_HALTS(_peripheral_) + +#define QM_IR_INT_MASK QM_IR_INT_SS_MASK +#define QM_IR_INT_HALT_MASK QM_IR_INT_SS_HALT_MASK +#define QM_IR_GET_MASK(_peripheral_) QM_IR_GET_SS_MASK(_peripheral_) +#define QM_IR_GET_HALT_MASK(_peripheral_) QM_IR_GET_SS_HALT_MASK(_peripheral_) +#else +#error "No active core selected." +#endif + +/** SS I2C Interrupt register map. */ +typedef struct { + QM_RW uint32_t err_mask; + QM_RW uint32_t rx_avail_mask; + QM_RW uint32_t tx_req_mask; + QM_RW uint32_t stop_det_mask; +} int_ss_i2c_reg_t; + +/** SS SPI Interrupt register map. */ +typedef struct { + QM_RW uint32_t err_int_mask; + QM_RW uint32_t rx_avail_mask; + QM_RW uint32_t tx_req_mask; +} int_ss_spi_reg_t; + +/** Interrupt register map. */ +typedef struct { + QM_RW uint32_t ss_adc_0_error_int_mask; /**< Sensor ADC 0 Error. */ + QM_RW uint32_t ss_adc_0_int_mask; /**< Sensor ADC 0. */ + QM_RW uint32_t ss_gpio_0_int_mask; /**< Sensor GPIO 0. */ + QM_RW uint32_t ss_gpio_1_int_mask; /**< Sensor GPIO 1. */ + int_ss_i2c_reg_t ss_i2c_0_int; /**< Sensor I2C 0 Masks. */ + int_ss_i2c_reg_t ss_i2c_1_int; /**< Sensor I2C 1 Masks. */ + int_ss_spi_reg_t ss_spi_0_int; /**< Sensor SPI 0 Masks. */ + int_ss_spi_reg_t ss_spi_1_int; /**< Sensor SPI 1 Masks. */ + QM_RW uint32_t i2c_master_0_int_mask; /**< I2C Master 0. */ + QM_RW uint32_t i2c_master_1_int_mask; /**< I2C Master 1. */ + QM_R uint32_t reserved; + QM_RW uint32_t spi_master_0_int_mask; /**< SPI Master 0. */ + QM_RW uint32_t spi_master_1_int_mask; /**< SPI Master 1. */ + QM_RW uint32_t spi_slave_0_int_mask; /**< SPI Slave 0. */ + QM_RW uint32_t uart_0_int_mask; /**< UART 0. */ + QM_RW uint32_t uart_1_int_mask; /**< UART 1. */ + QM_RW uint32_t i2s_0_int_mask; /**< I2S 0. */ + QM_RW uint32_t gpio_0_int_mask; /**< GPIO 0. */ + QM_RW uint32_t pwm_0_int_mask; /**< PWM 0. */ + QM_RW uint32_t usb_0_int_mask; /**< USB 0. */ + QM_RW uint32_t rtc_0_int_mask; /**< RTC 0. */ + QM_RW uint32_t wdt_0_int_mask; /**< WDT 0. */ + QM_RW uint32_t dma_0_int_0_mask; /**< DMA 0 Ch 0. */ + QM_RW uint32_t dma_0_int_1_mask; /**< DMA 0 Ch 1. */ + QM_RW uint32_t dma_0_int_2_mask; /**< DMA 0 Ch 2. */ + QM_RW uint32_t dma_0_int_3_mask; /**< DMA 0 Ch 3. */ + QM_RW uint32_t dma_0_int_4_mask; /**< DMA 0 Ch 4. */ + QM_RW uint32_t dma_0_int_5_mask; /**< DMA 0 Ch 5. */ + QM_RW uint32_t dma_0_int_6_mask; /**< DMA 0 Ch 6. */ + QM_RW uint32_t dma_0_int_7_mask; /**< DMA 0 Ch 7. */ + /** Mailbox 0 Combined 8 Channel Host and Sensor Masks. */ + QM_RW uint32_t mailbox_0_int_mask; + /** Comparator Sensor Halt Mask. */ + QM_RW uint32_t comparator_0_ss_halt_int_mask; + /** Comparator Host Halt Mask. */ + QM_RW uint32_t comparator_0_host_halt_int_mask; + /** Comparator Sensor Mask. */ + QM_RW uint32_t comparator_0_ss_int_mask; + /** Comparator Host Mask. */ + QM_RW uint32_t comparator_0_host_int_mask; + QM_RW uint32_t host_bus_error_int_mask; /**< Host bus error. */ + QM_RW uint32_t dma_0_error_int_mask; /**< DMA 0 Error. */ + QM_RW uint32_t sram_mpr_0_int_mask; /**< SRAM MPR 0. */ + QM_RW uint32_t flash_mpr_0_int_mask; /**< Flash MPR 0. */ + QM_RW uint32_t flash_mpr_1_int_mask; /**< Flash MPR 1. */ + QM_RW uint32_t aonpt_0_int_mask; /**< AONPT 0. */ + QM_RW uint32_t adc_0_pwr_int_mask; /**< ADC 0 PWR. */ + QM_RW uint32_t adc_0_cal_int_mask; /**< ADC 0 CAL. */ + QM_RW uint32_t aon_gpio_0_int_mask; /**< AON GPIO 0. */ + QM_RW uint32_t lock_int_mask_reg; /**< Interrupt Mask Lock Register. */ +} qm_interrupt_router_reg_t; + +/* Number of SCSS interrupt mask registers (excluding mask lock register). */ +#define QM_INTERRUPT_ROUTER_MASK_NUMREG \ + ((sizeof(qm_interrupt_router_reg_t) / sizeof(uint32_t)) - 1) + +/* Default POR SCSS interrupt mask (all interrupts masked). */ +#define QM_INTERRUPT_ROUTER_MASK_DEFAULT (0xFFFFFFFF) + +#if (UNIT_TEST) +qm_interrupt_router_reg_t test_interrupt_router; +#define QM_INTERRUPT_ROUTER \ + ((qm_interrupt_router_reg_t *)(&test_interrupt_router)) + +#else +/* System control subsystem interrupt masking register block. */ +#define QM_INTERRUPT_ROUTER_BASE (0xB0800400) +#define QM_INTERRUPT_ROUTER \ + ((qm_interrupt_router_reg_t *)QM_INTERRUPT_ROUTER_BASE) +#endif + +#define QM_IR_DMA_ERROR_HOST_MASK (0x000000FF) +#define QM_IR_DMA_ERROR_SS_MASK (0x0000FF00) + +/** @} */ + +#endif /* __QM_INTERRUPT_ROUTER_REGS_H__ */ diff --git a/libraries/CuriePowerManagement/src/qmsi/qm_sensor_regs.h b/libraries/CuriePowerManagement/src/qmsi/qm_sensor_regs.h new file mode 100644 index 00000000..324d001e --- /dev/null +++ b/libraries/CuriePowerManagement/src/qmsi/qm_sensor_regs.h @@ -0,0 +1,673 @@ +/* + * Copyright (c) 2016, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __SENSOR_REGISTERS_H__ +#define __SENSOR_REGISTERS_H__ + +/** + * Quark SE SoC Sensor Subsystem Registers. + * + * For detailed description please read the SOC datasheet. + * + * @defgroup groupSSSEREG SoC Registers (Sensor Subsystem) + * @{ + */ + +#define BIT(x) (1U << (x)) + +/* Bitwise OR operation macro for registers in the auxiliary memory space. */ +#define QM_SS_REG_AUX_OR(reg, mask) \ + (__builtin_arc_sr(__builtin_arc_lr(reg) | (mask), reg)) +/* Bitwise NAND operation macro for registers in the auxiliary memory space. */ +#define QM_SS_REG_AUX_NAND(reg, mask) \ + (__builtin_arc_sr(__builtin_arc_lr(reg) & (~(mask)), reg)) + +/* Sensor Subsystem status32 register. */ +#define QM_SS_AUX_STATUS32 (0xA) +/** Interrupt priority threshold. */ +#define QM_SS_STATUS32_E_MASK (0x1E) +/** Interrupt enable. */ +#define QM_SS_STATUS32_IE_MASK BIT(31) +/* Sensor Subsystem control register. */ +#define QM_SS_AUX_IC_CTRL (0x11) +/* Sensor Subsystem cache invalidate register. */ +#define QM_SS_AUX_IC_IVIL (0x19) +/* Sensor Subsystem vector base register. */ +#define QM_SS_AUX_INT_VECTOR_BASE (0x25) + +/** + * @name SS Interrupt + * @{ + */ + +#define QM_SS_EXCEPTION_NUM (16) /* Exceptions and traps in ARC EM core. */ +#define QM_SS_INT_TIMER_NUM (2) /* Internal interrupts in ARC EM core. */ +#define QM_SS_IRQ_SENSOR_NUM (18) /* IRQ's from the Sensor Subsystem. */ +#define QM_SS_IRQ_COMMON_NUM (32) /* IRQ's from the common SoC fabric. */ +#define QM_SS_INT_VECTOR_NUM \ + (QM_SS_EXCEPTION_NUM + QM_SS_INT_TIMER_NUM + QM_SS_IRQ_SENSOR_NUM + \ + QM_SS_IRQ_COMMON_NUM) +#define QM_SS_IRQ_NUM (QM_SS_IRQ_SENSOR_NUM + QM_SS_IRQ_COMMON_NUM) + +/** + * SS IRQ context type. + * + * Applications should not modify the content. + * This structure is only intended to be used by + * qm_irq_save_context and qm_irq_restore_context functions. + */ +typedef struct { + uint32_t status32_irq_threshold; /**< STATUS32 Interrupt Threshold. */ + uint32_t status32_irq_enable; /**< STATUS32 Interrupt Enable. */ + uint32_t irq_ctrl; /**< Interrupt Context Saving Control Register. */ + + /** + * IRQ configuration: + * - IRQ Priority:BIT(6):BIT(2) + * - IRQ Trigger:BIT(1) + * - IRQ Enable:BIT(0) + */ + uint8_t irq_config[QM_SS_INT_VECTOR_NUM - 1]; +} qm_irq_context_t; + +/** General Purpose register map. */ +typedef struct { + volatile uint32_t gps0; /**< General Purpose Sticky Register 0 */ + volatile uint32_t gps1; /**< General Purpose Sticky Register 1 */ + volatile uint32_t gps2; /**< General Purpose Sticky Register 2 */ + volatile uint32_t gps3; /**< General Purpose Sticky Register 3 */ + volatile uint32_t reserved; + volatile uint32_t gp0; /**< General Purpose Scratchpad Register 0 */ + volatile uint32_t gp1; /**< General Purpose Scratchpad Register 1 */ + volatile uint32_t gp2; /**< General Purpose Scratchpad Register 2 */ + volatile uint32_t gp3; /**< General Purpose Scratchpad Register 3 */ + volatile uint32_t reserved1; + volatile uint32_t id; /**< Identification Register */ + volatile uint32_t rev; /**< Revision Register */ + volatile uint32_t wo_sp; /**< Write-One-to-Set Scratchpad Register */ + volatile uint32_t + wo_st; /**< Write-One-to-Set Sticky Scratchpad Register */ +} qm_scss_gp_reg_t; + +#define QM_SCSS_GP_BASE (0xB0800100) +#define QM_SCSS_GP ((qm_scss_gp_reg_t *)QM_SCSS_GP_BASE) + +/* The GPS0 register usage. */ +#define QM_GPS0_BIT_FM (0) /**< Start Firmware Manager. */ +#define QM_GPS0_BIT_X86_WAKEUP (1) /**< Lakemont core reset type. */ +#define QM_GPS0_BIT_SENSOR_WAKEUP (2) /**< Sensor core reset type. */ + +/** System Core register map. */ +typedef struct { + volatile uint32_t osc0_cfg0; /**< Hybrid Oscillator Configuration 0. */ + volatile uint32_t osc0_stat1; /**< Hybrid Oscillator status 1. */ + volatile uint32_t osc0_cfg1; /**< Hybrid Oscillator configuration 1. */ + volatile uint32_t osc1_stat0; /**< RTC Oscillator status 0. */ + volatile uint32_t osc1_cfg0; /**< RTC Oscillator Configuration 0. */ + volatile uint32_t usb_pll_cfg0; /**< USB Phase lock look configuration. */ + volatile uint32_t + ccu_periph_clk_gate_ctl; /**< Peripheral Clock Gate Control. */ + volatile uint32_t + ccu_periph_clk_div_ctl0; /**< Peripheral Clock Divider Control. 0 */ + volatile uint32_t + ccu_gpio_db_clk_ctl; /**< Peripheral Clock Divider Control 1. */ + volatile uint32_t + ccu_ext_clock_ctl; /**< External Clock Control Register. */ + /** Sensor Subsystem peripheral clock gate control. */ + volatile uint32_t ccu_ss_periph_clk_gate_ctl; + volatile uint32_t ccu_lp_clk_ctl; /**< System Low Power Clock Control. */ + volatile uint32_t reserved; + volatile uint32_t ccu_mlayer_ahb_ctl; /**< AHB Control Register. */ + volatile uint32_t ccu_sys_clk_ctl; /**< System Clock Control Register. */ + volatile uint32_t osc_lock_0; /**< Clocks Lock Register. */ +} qm_scss_ccu_reg_t; + +#define QM_SCSS_CCU ((qm_scss_ccu_reg_t *)SCSS_REGISTER_BASE) + +/** Power Management register map. */ +typedef struct { + volatile uint32_t p_lvl2; /**< Processor level 2 */ + volatile uint32_t reserved[4]; + volatile uint32_t pm1c; /**< Power management 1 control */ + volatile uint32_t reserved1[9]; + volatile uint32_t aon_vr; /**< AON Voltage Regulator */ + volatile uint32_t plat3p3_vr; /**< Platform 3p3 voltage regulator */ + volatile uint32_t plat1p8_vr; /**< Platform 1p8 voltage regulator */ + volatile uint32_t host_vr; /**< Host Voltage Regulator */ + volatile uint32_t slp_cfg; /**< Sleeping Configuration */ + /** Power Management Network (PMNet) Control and Status */ + volatile uint32_t pmnetcs; + volatile uint32_t pm_wait; /**< Power Management Wait */ + volatile uint32_t reserved2; + volatile uint32_t p_sts; /**< Processor Status */ + volatile uint32_t reserved3[3]; + volatile uint32_t rstc; /**< Reset Control */ + volatile uint32_t rsts; /**< Reset Status */ + volatile uint32_t reserved4[6]; + volatile uint32_t vr_lock; /**< Voltage regulator lock */ + volatile uint32_t pm_lock; /**< Power Management Lock */ +} qm_scss_pmu_reg_t; + +#define QM_SCSS_PMU_BASE (0xB0800504) +#define QM_SCSS_PMU ((qm_scss_pmu_reg_t *)QM_SCSS_PMU_BASE) + +#define QM_SS_CFG_ARC_RUN_REQ_A BIT(24) +#define QM_P_STS_HALT_INTERRUPT_REDIRECTION BIT(26) +#define QM_P_STS_ARC_HALT BIT(14) + +#define QM_AON_VR_VSEL_MASK (0xFFE0) +#define QM_AON_VR_VSEL_1V2 (0x8) +#define QM_AON_VR_VSEL_1V35 (0xB) +#define QM_AON_VR_VSEL_1V8 (0x10) +#define QM_AON_VR_EN BIT(7) +#define QM_AON_VR_VSTRB BIT(5) + +#define QM_SCSS_SLP_CFG_LPMODE_EN BIT(8) +#define QM_SCSS_SLP_CFG_RTC_DIS BIT(7) +#define QM_SCSS_PM1C_SLPEN BIT(13) +#define QM_SCSS_HOST_VR_EN BIT(7) +#define QM_SCSS_PLAT3P3_VR_EN BIT(7) +#define QM_SCSS_PLAT1P8_VR_EN BIT(7) +#define QM_SCSS_HOST_VR_VREG_SEL BIT(6) +#define QM_SCSS_PLAT3P3_VR_VREG_SEL BIT(6) +#define QM_SCSS_PLAT1P8_VR_VREG_SEL BIT(6) +#define QM_SCSS_VR_ROK BIT(10) +#define QM_SCSS_VR_EN BIT(7) +#define QM_SCSS_VR_VREG_SEL BIT(6) + +#define QM_SCSS_CCU_SS_LPS_EN BIT(0) + +typedef enum { + QM_SS_IRQ_LEVEL_SENSITIVE = 0, + QM_SS_IRQ_EDGE_SENSITIVE = 1 +} qm_ss_irq_trigger_t; + +#define QM_SS_AUX_IRQ_CTRL (0xE) +#define QM_SS_AUX_IRQ_HINT (0x201) +#define QM_SS_AUX_IRQ_PRIORITY (0x206) +#define QM_SS_AUX_IRQ_STATUS (0x406) +#define QM_SS_AUX_IRQ_SELECT (0x40B) +#define QM_SS_AUX_IRQ_ENABLE (0x40C) +#define QM_SS_AUX_IRQ_TRIGGER (0x40D) + +/** Always-On Timer Interrupt. */ +#define QM_IRQ_AONPT_0_INT 28 +#define QM_IRQ_AONPT_0_INT_MASK_OFFSET 32 +#define QM_IRQ_AONPT_0_INT_VECTOR 64 + +/** RTC Single Interrupt. */ +#define QM_IRQ_RTC_0_INT 11 +#define QM_IRQ_RTC_0_INT_MASK_OFFSET 12 +#define QM_IRQ_RTC_0_INT_VECTOR 47 + +/** @} */ + +/** + * @name SS Timer + * @{ + */ + +typedef enum { + QM_SS_TIMER_COUNT = 0, + QM_SS_TIMER_CONTROL, + QM_SS_TIMER_LIMIT +} qm_ss_timer_reg_t; + +/** + * Sensor Subsystem Timers. + */ +typedef enum { QM_SS_TIMER_0 = 0, QM_SS_TIMER_NUM } qm_ss_timer_t; + +/* + * SS TIMER context type. + * + * Application should not modify the content. + * This structure is only intended to be used by the qm_ss_timer_save_context + * and qm_ss_timer_restore_context functions. + */ +typedef struct { + uint32_t timer_count; /**< Timer count. */ + uint32_t timer_control; /**< Timer control. */ + uint32_t timer_limit; /**< Timer limit. */ +} qm_ss_timer_context_t; + +#define QM_SS_TIMER_0_BASE (0x21) +#define QM_SS_TIMER_1_BASE (0x100) +#define QM_SS_TSC_BASE QM_SS_TIMER_1_BASE + +#define QM_SS_TIMER_CONTROL_INT_EN_OFFSET (0) +#define QM_SS_TIMER_CONTROL_NON_HALTED_OFFSET (1) +#define QM_SS_TIMER_CONTROL_WATCHDOG_OFFSET (2) +#define QM_SS_TIMER_CONTROL_INT_PENDING_OFFSET (3) +/** @} */ + +/** + * GPIO registers and definitions. + * + * @name SS GPIO + * @{ + */ + +/** Sensor Subsystem GPIO register block type. */ +typedef enum { + QM_SS_GPIO_SWPORTA_DR = 0, + QM_SS_GPIO_SWPORTA_DDR, + QM_SS_GPIO_INTEN = 3, + QM_SS_GPIO_INTMASK, + QM_SS_GPIO_INTTYPE_LEVEL, + QM_SS_GPIO_INT_POLARITY, + QM_SS_GPIO_INTSTATUS, + QM_SS_GPIO_DEBOUNCE, + QM_SS_GPIO_PORTA_EOI, + QM_SS_GPIO_EXT_PORTA, + QM_SS_GPIO_LS_SYNC +} qm_ss_gpio_reg_t; + +/** + * SS GPIO context type. + * + * Application should not modify the content. + * This structure is only intended to be used by the qm_ss_gpio_save_context and + * qm_ss_gpio_restore_context functions. + */ +typedef struct { + uint32_t gpio_swporta_dr; /**< Port A Data. */ + uint32_t gpio_swporta_ddr; /**< Port A Data Direction. */ + uint32_t gpio_inten; /**< Interrupt Enable. */ + uint32_t gpio_intmask; /**< Interrupt Mask. */ + uint32_t gpio_inttype_level; /**< Interrupt Type. */ + uint32_t gpio_int_polarity; /**< Interrupt Polarity. */ + uint32_t gpio_debounce; /**< Debounce Enable. */ + uint32_t gpio_ls_sync; /**< Synchronization Level. */ +} qm_ss_gpio_context_t; + +#define QM_SS_GPIO_NUM_PINS (16) +#define QM_SS_GPIO_LS_SYNC_CLK_EN BIT(31) +#define QM_SS_GPIO_LS_SYNC_SYNC_LVL BIT(0) + +/** Sensor Subsystem GPIO. */ +typedef enum { QM_SS_GPIO_0 = 0, QM_SS_GPIO_1, QM_SS_GPIO_NUM } qm_ss_gpio_t; + +#define QM_SS_GPIO_0_BASE (0x80017800) +#define QM_SS_GPIO_1_BASE (0x80017900) + +/** @} */ + +/** + * I2C registers and definitions. + * + * @name SS I2C + * @{ + */ + +/** Sensor Subsystem I2C register block type. */ +typedef enum { + QM_SS_I2C_CON = 0, + QM_SS_I2C_DATA_CMD, + QM_SS_I2C_SS_SCL_CNT, + QM_SS_I2C_FS_SCL_CNT = 0x04, + QM_SS_I2C_INTR_STAT = 0x06, + QM_SS_I2C_INTR_MASK, + QM_SS_I2C_TL, + QM_SS_I2C_INTR_CLR = 0x0A, + QM_SS_I2C_STATUS, + QM_SS_I2C_TXFLR, + QM_SS_I2C_RXFLR, + QM_SS_I2C_SDA_CONFIG, + QM_SS_I2C_TX_ABRT_SOURCE, + QM_SS_I2C_ENABLE_STATUS = 0x11 +} qm_ss_i2c_reg_t; + +/** + * SS I2C context type. + * + * Application should not modify the content. + * This structure is only intended to be used by the qm_ss_gpio_save_context and + * qm_ss_gpio_restore_context functions. + */ +typedef struct { + uint32_t i2c_con; + uint32_t i2c_ss_scl_cnt; + uint32_t i2c_fs_scl_cnt; +} qm_ss_i2c_context_t; + +#define QM_SS_I2C_CON_ENABLE BIT(0) +#define QM_SS_I2C_CON_ABORT BIT(1) +#define QM_SS_I2C_CON_SPEED_SS BIT(3) +#define QM_SS_I2C_CON_SPEED_FS BIT(4) +#define QM_SS_I2C_CON_SPEED_MASK (0x18) +#define QM_SS_I2C_CON_IC_10BITADDR BIT(5) +#define QM_SS_I2C_CON_IC_10BITADDR_OFFSET (5) +#define QM_SS_I2C_CON_IC_10BITADDR_MASK (5) +#define QM_SS_I2C_CON_RESTART_EN BIT(7) +#define QM_SS_I2C_CON_TAR_SAR_OFFSET (9) +#define QM_SS_I2C_CON_TAR_SAR_MASK (0x7FE00) +#define QM_SS_I2C_CON_TAR_SAR_10_BIT_MASK (0x3FF) +#define QM_SS_I2C_CON_SPKLEN_OFFSET (22) +#define QM_SS_I2C_CON_SPKLEN_MASK (0x3FC00000) +#define QM_SS_I2C_CON_CLK_ENA BIT(31) + +#define QM_SS_I2C_DATA_CMD_CMD BIT(8) +#define QM_SS_I2C_DATA_CMD_STOP BIT(9) +#define QM_SS_I2C_DATA_CMD_PUSH (0xC0000000) +#define QM_SS_I2C_DATA_CMD_POP (0x80000000) + +#define QM_SS_I2C_SS_FS_SCL_CNT_HCNT_OFFSET (16) +#define QM_SS_I2C_SS_FS_SCL_CNT_16BIT_MASK (0xFFFF) + +#define QM_SS_I2C_INTR_STAT_RX_UNDER BIT(0) +#define QM_SS_I2C_INTR_STAT_RX_OVER BIT(1) +#define QM_SS_I2C_INTR_STAT_RX_FULL BIT(2) +#define QM_SS_I2C_INTR_STAT_TX_OVER BIT(3) +#define QM_SS_I2C_INTR_STAT_TX_EMPTY BIT(4) +#define QM_SS_I2C_INTR_STAT_TX_ABRT BIT(6) + +#define QM_SS_I2C_INTR_MASK_ALL (0x0) +#define QM_SS_I2C_INTR_MASK_RX_UNDER BIT(0) +#define QM_SS_I2C_INTR_MASK_RX_OVER BIT(1) +#define QM_SS_I2C_INTR_MASK_RX_FULL BIT(2) +#define QM_SS_I2C_INTR_MASK_TX_OVER BIT(3) +#define QM_SS_I2C_INTR_MASK_TX_EMPTY BIT(4) +#define QM_SS_I2C_INTR_MASK_TX_ABRT BIT(6) + +#define QM_SS_I2C_TL_TX_TL_OFFSET (16) +#define QM_SS_I2C_TL_RX_TL_MASK (0xFF) +#define QM_SS_I2C_TL_TX_TL_MASK (0xFF0000) + +#define QM_SS_I2C_INTR_CLR_ALL (0xFF) +#define QM_SS_I2C_INTR_CLR_TX_ABRT BIT(6) + +#define QM_SS_I2C_TX_ABRT_SOURCE_NAK_MASK (0x09) +#define QM_SS_I2C_TX_ABRT_SOURCE_ALL_MASK (0x1FFFF) +#define QM_SS_I2C_TX_ABRT_SBYTE_NORSTRT BIT(9) +#define QM_SS_I2C_TX_ABRT_SOURCE_ART_LOST BIT(12) + +#define QM_SS_I2C_ENABLE_CONTROLLER_EN BIT(0) +#define QM_SS_I2C_ENABLE_STATUS_IC_EN BIT(0) + +#define QM_SS_I2C_STATUS_BUSY_MASK (0x21) +#define QM_SS_I2C_STATUS_RFNE BIT(3) +#define QM_SS_I2C_STATUS_TFE BIT(2) +#define QM_SS_I2C_STATUS_TFNF BIT(1) + +#define QM_SS_I2C_IC_LCNT_MAX (65525) +#define QM_SS_I2C_IC_LCNT_MIN (8) +#define QM_SS_I2C_IC_HCNT_MAX (65525) +#define QM_SS_I2C_IC_HCNT_MIN (6) + +#define QM_SS_I2C_FIFO_SIZE (8) + +/** Sensor Subsystem I2C */ +typedef enum { QM_SS_I2C_0 = 0, QM_SS_I2C_1, QM_SS_I2C_NUM } qm_ss_i2c_t; + +#define QM_SS_I2C_0_BASE (0x80012000) +#define QM_SS_I2C_1_BASE (0x80012100) + +/** @} */ +/** Sensor Subsystem ADC @{*/ + +/** Sensor Subsystem ADC registers */ +typedef enum { + QM_SS_ADC_SET = 0, /**< ADC and sequencer settings register. */ + QM_SS_ADC_DIVSEQSTAT, /**< ADC clock and sequencer status register. */ + QM_SS_ADC_SEQ, /**< ADC sequence entry register. */ + QM_SS_ADC_CTRL, /**< ADC control register. */ + QM_SS_ADC_INTSTAT, /**< ADC interrupt status register. */ + QM_SS_ADC_SAMPLE /**< ADC sample register. */ +} qm_ss_adc_reg_t; + +/** Sensor Subsystem ADC */ +typedef enum { + QM_SS_ADC_0 = 0, /**< ADC first module. */ + QM_SS_ADC_NUM +} qm_ss_adc_t; + +/** + * SS ADC context type. + * + * The application should not modify the content of this structure. + * + * This structure is intented to be used by qm_ss_adc_save_context and + * qm_ss_adc_restore_context functions only. + */ +typedef struct { + uint32_t adc_set; /**< ADC settings. */ + uint32_t adc_divseqstat; /**< ADC clock divider and sequencer status. */ + uint32_t adc_seq; /**< ADC sequencer entry. */ + uint32_t adc_ctrl; /**< ADC control. */ +} qm_ss_adc_context_t; + +/* SS ADC register base. */ +#define QM_SS_ADC_BASE (0x80015000) + +/* For 1MHz, the max divisor is 7. */ +#define QM_SS_ADC_DIV_MAX (7) + +#define QM_SS_ADC_FIFO_LEN (32) + +#define QM_SS_ADC_SET_POP_RX BIT(31) +#define QM_SS_ADC_SET_FLUSH_RX BIT(30) +#define QM_SS_ADC_SET_THRESHOLD_MASK (0x3F000000) +#define QM_SS_ADC_SET_THRESHOLD_OFFSET (24) +#define QM_SS_ADC_SET_SEQ_ENTRIES_MASK (0x3F0000) +#define QM_SS_ADC_SET_SEQ_ENTRIES_OFFSET (16) +#define QM_SS_ADC_SET_SEQ_MODE BIT(13) +#define QM_SS_ADC_SET_SAMPLE_WIDTH_MASK (0x1F) + +#define QM_SS_ADC_DIVSEQSTAT_CLK_RATIO_MASK (0x1FFFFF) + +#define QM_SS_ADC_CTRL_CLR_SEQERROR BIT(19) +#define QM_SS_ADC_CTRL_CLR_UNDERFLOW BIT(18) +#define QM_SS_ADC_CTRL_CLR_OVERFLOW BIT(17) +#define QM_SS_ADC_CTRL_CLR_DATA_A BIT(16) +#define QM_SS_ADC_CTRL_MSK_SEQERROR BIT(11) +#define QM_SS_ADC_CTRL_MSK_UNDERFLOW BIT(10) +#define QM_SS_ADC_CTRL_MSK_OVERFLOW BIT(9) +#define QM_SS_ADC_CTRL_MSK_DATA_A BIT(8) +#define QM_SS_ADC_CTRL_SEQ_TABLE_RST BIT(6) +#define QM_SS_ADC_CTRL_SEQ_PTR_RST BIT(5) +#define QM_SS_ADC_CTRL_SEQ_START BIT(4) +#define QM_SS_ADC_CTRL_CLK_ENA BIT(2) +#define QM_SS_ADC_CTRL_ADC_ENA BIT(1) + +#define QM_SS_ADC_CTRL_MSK_ALL_INT (0xF00) +#define QM_SS_ADC_CTRL_CLR_ALL_INT (0xF0000) + +#define QM_SS_ADC_SEQ_DELAYODD_OFFSET (21) +#define QM_SS_ADC_SEQ_MUXODD_OFFSET (16) +#define QM_SS_ADC_SEQ_DELAYEVEN_OFFSET (5) + +#define QM_SS_ADC_SEQ_DUMMY (0x480) + +#define QM_SS_ADC_INTSTAT_SEQERROR BIT(3) +#define QM_SS_ADC_INTSTAT_UNDERFLOW BIT(2) +#define QM_SS_ADC_INTSTAT_OVERFLOW BIT(1) +#define QM_SS_ADC_INTSTAT_DATA_A BIT(0) + +/** End of Sensor Subsystem ADC @}*/ + +/** + * CREG Registers. + * + * @name SS CREG + * @{ + */ + +/* Sensor Subsystem CREG */ +typedef enum { + QM_SS_IO_CREG_MST0_CTRL = 0x0, /**< Master control register. */ + QM_SS_IO_CREG_SLV0_OBSR = 0x80, /**< Slave control register. */ + QM_SS_IO_CREG_SLV1_OBSR = 0x180 /**< Slave control register. */ +} qm_ss_creg_reg_t; + +/* MST0_CTRL fields */ +#define QM_SS_IO_CREG_MST0_CTRL_ADC_PWR_MODE_OFFSET (1) +#define QM_SS_IO_CREG_MST0_CTRL_ADC_PWR_MODE_MASK (0x7) +#define QM_SS_IO_CREG_MST0_CTRL_ADC_DELAY_OFFSET (3) +#define QM_SS_IO_CREG_MST0_CTRL_ADC_DELAY_MASK (0xFFF8) +#define QM_SS_IO_CREG_MST0_CTRL_ADC_CAL_REQ BIT(16) +#define QM_SS_IO_CREG_MST0_CTRL_ADC_CAL_CMD_OFFSET (17) +#define QM_SS_IO_CREG_MST0_CTRL_ADC_CAL_CMD_MASK (0xE0000) +#define QM_SS_IO_CREG_MST0_CTRL_ADC_CAL_VAL_OFFSET (20) +#define QM_SS_IO_CREG_MST0_CTRL_ADC_CAL_VAL_MASK (0x7F00000) +#define QM_SS_IO_CREG_MST0_CTRL_ADC_CAL_VAL_MAX (0x7F) +#define QM_SS_IO_CREG_MST0_CTRL_SPI1_CLK_GATE BIT(27) +#define QM_SS_IO_CREG_MST0_CTRL_SPI0_CLK_GATE BIT(28) +#define QM_SS_IO_CREG_MST0_CTRL_I2C0_CLK_GATE BIT(29) +#define QM_SS_IO_CREG_MST0_CTRL_I2C1_CLK_GATE BIT(30) +#define QM_SS_IO_CREG_MST0_CTRL_ADC_CLK_GATE BIT(31) +/* SLV0_OBSR fields */ +#define QM_SS_IO_CREG_SLV0_OBSR_ADC_CAL_VAL_OFFSET (5) +#define QM_SS_IO_CREG_SLV0_OBSR_ADC_CAL_VAL_MASK (0xFE0) +#define QM_SS_IO_CREG_SLV0_OBSR_ADC_CAL_ACK BIT(4) +#define QM_SS_IO_CREG_SLV0_OBSR_ADC_PWR_MODE_STS BIT(3) + +#define SS_CLK_PERIPH_ALL_IN_CREG \ + (SS_CLK_PERIPH_ADC | SS_CLK_PERIPH_I2C_1 | SS_CLK_PERIPH_I2C_0 | \ + SS_CLK_PERIPH_SPI_1 | SS_CLK_PERIPH_SPI_0) + +/* SS CREG base. */ +#define QM_SS_CREG_BASE (0x80018000) + +/** @} */ + +/** + * I2C registers and definitions. + * + * @name SS SPI + * @{ + */ + +/** Sensor Subsystem SPI register map. */ +typedef enum { + QM_SS_SPI_CTRL = 0, /**< SPI control register. */ + QM_SS_SPI_SPIEN = 2, /**< SPI enable register. */ + QM_SS_SPI_TIMING = 4, /**< SPI serial clock divider value. */ + QM_SS_SPI_FTLR, /**< Threshold value for TX/RX FIFO. */ + QM_SS_SPI_TXFLR = 7, /**< Number of valid data entries in TX FIFO. */ + QM_SS_SPI_RXFLR, /**< Number of valid data entries in RX FIFO. */ + QM_SS_SPI_SR, /**< SPI status register. */ + QM_SS_SPI_INTR_STAT, /**< Interrupt status register. */ + QM_SS_SPI_INTR_MASK, /**< Interrupt mask register. */ + QM_SS_SPI_CLR_INTR, /**< Interrupt clear register. */ + QM_SS_SPI_DR, /**< RW buffer for FIFOs. */ +} qm_ss_spi_reg_t; + +/** + * Sensor Subsystem SPI context type. + * + * Applications should not modify the content. + * This structure is only intended to be used by + * the qm_ss_spi_save_context and qm_ss_spi_restore_context functions. + */ +typedef struct { + uint32_t spi_ctrl; /**< Control Register. */ + uint32_t spi_spien; /**< SPI Enable Register. */ + uint32_t spi_timing; /**< Timing Register. */ +} qm_ss_spi_context_t; + +/** Sensor Subsystem SPI modules. */ +typedef enum { + QM_SS_SPI_0 = 0, /**< SPI module 0 */ + QM_SS_SPI_1, /**< SPI module 1 */ + QM_SS_SPI_NUM +} qm_ss_spi_t; + +#define QM_SS_SPI_0_BASE (0x80010000) +#define QM_SS_SPI_1_BASE (0x80010100) + +#define QM_SS_SPI_CTRL_DFS_OFFS (0) +#define QM_SS_SPI_CTRL_DFS_MASK (0x0000000F) +#define QM_SS_SPI_CTRL_BMOD_OFFS (6) +#define QM_SS_SPI_CTRL_BMOD_MASK (0x000000C0) +#define QM_SS_SPI_CTRL_SCPH BIT(6) +#define QM_SS_SPI_CTRL_SCPOL BIT(7) +#define QM_SS_SPI_CTRL_TMOD_OFFS (8) +#define QM_SS_SPI_CTRL_TMOD_MASK (0x00000300) +#define QM_SS_SPI_CTRL_SRL BIT(11) +#define QM_SS_SPI_CTRL_CLK_ENA BIT(15) +#define QM_SS_SPI_CTRL_NDF_OFFS (16) +#define QM_SS_SPI_CTRL_NDF_MASK (0xFFFF0000) + +#define QM_SS_SPI_SPIEN_EN BIT(0) +#define QM_SS_SPI_SPIEN_SER_OFFS (4) +#define QM_SS_SPI_SPIEN_SER_MASK (0x000000F0) + +#define QM_SS_SPI_TIMING_SCKDV_OFFS (0) +#define QM_SS_SPI_TIMING_SCKDV_MASK (0x0000FFFF) +#define QM_SS_SPI_TIMING_RSD_OFFS (16) +#define QM_SS_SPI_TIMING_RSD_MASK (0x00FF0000) + +#define QM_SS_SPI_FTLR_RFT_OFFS (0) +#define QM_SS_SPI_FTLR_RFT_MASK (0x0000FFFF) +#define QM_SS_SPI_FTLR_TFT_OFFS (16) +#define QM_SS_SPI_FTLR_TFT_MASK (0xFFFF0000) + +#define QM_SS_SPI_SR_BUSY BIT(0) +#define QM_SS_SPI_SR_TFNF BIT(1) +#define QM_SS_SPI_SR_TFE BIT(2) +#define QM_SS_SPI_SR_RFNE BIT(3) +#define QM_SS_SPI_SR_RFF BIT(4) + +#define QM_SS_SPI_INTR_TXEI BIT(0) +#define QM_SS_SPI_INTR_TXOI BIT(1) +#define QM_SS_SPI_INTR_RXUI BIT(2) +#define QM_SS_SPI_INTR_RXOI BIT(3) +#define QM_SS_SPI_INTR_RXFI BIT(4) +#define QM_SS_SPI_INTR_ALL (0x0000001F) + +#define QM_SS_SPI_INTR_STAT_TXEI QM_SS_SPI_INTR_TXEI +#define QM_SS_SPI_INTR_STAT_TXOI QM_SS_SPI_INTR_TXOI +#define QM_SS_SPI_INTR_STAT_RXUI QM_SS_SPI_INTR_RXUI +#define QM_SS_SPI_INTR_STAT_RXOI QM_SS_SPI_INTR_RXOI +#define QM_SS_SPI_INTR_STAT_RXFI QM_SS_SPI_INTR_RXFI + +#define QM_SS_SPI_INTR_MASK_TXEI QM_SS_SPI_INTR_TXEI +#define QM_SS_SPI_INTR_MASK_TXOI QM_SS_SPI_INTR_TXOI +#define QM_SS_SPI_INTR_MASK_RXUI QM_SS_SPI_INTR_RXUI +#define QM_SS_SPI_INTR_MASK_RXOI QM_SS_SPI_INTR_RXOI +#define QM_SS_SPI_INTR_MASK_RXFI QM_SS_SPI_INTR_RXFI + +#define QM_SS_SPI_CLR_INTR_TXEI QM_SS_SPI_INTR_TXEI +#define QM_SS_SPI_CLR_INTR_TXOI QM_SS_SPI_INTR_TXOI +#define QM_SS_SPI_CLR_INTR_RXUI QM_SS_SPI_INTR_RXUI +#define QM_SS_SPI_CLR_INTR_RXOI QM_SS_SPI_INTR_RXOI +#define QM_SS_SPI_CLR_INTR_RXFI QM_SS_SPI_INTR_RXFI + +#define QM_SS_SPI_DR_DR_OFFS (0) +#define QM_SS_SPI_DR_DR_MASK (0x0000FFFF) +#define QM_SS_SPI_DR_WR BIT(30) +#define QM_SS_SPI_DR_STROBE BIT(31) +#define QM_SS_SPI_DR_W_MASK (0xc0000000) +#define QM_SS_SPI_DR_R_MASK (0x80000000) + +/** @} */ +/** @} */ + +#endif /* __SENSOR_REGISTERS_H__ */ diff --git a/libraries/CuriePowerManagement/src/qmsi/qm_soc_interrupts.h b/libraries/CuriePowerManagement/src/qmsi/qm_soc_interrupts.h new file mode 100644 index 00000000..9acd4c35 --- /dev/null +++ b/libraries/CuriePowerManagement/src/qmsi/qm_soc_interrupts.h @@ -0,0 +1,410 @@ +/* + * Copyright (c) 2016, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __QM_SOC_INTERRUPTS_H__ +#define __QM_SOC_INTERRUPTS_H__ + +/** + * Quark SE SoC Interrupts. + * + * @defgroup groupQUARKSESEINT SoC Interrupts (SE) + * @{ + */ + +#if (QM_LAKEMONT) + +/* x86 internal interrupt vectors. */ +#define QM_X86_DIVIDE_ERROR_INT (0) +#define QM_X86_DEBUG_EXCEPTION_INT (1) +#define QM_X86_NMI_INTERRUPT_INT (2) +#define QM_X86_BREAKPOINT_INT (3) +#define QM_X86_OVERFLOW_INT (4) +#define QM_X86_BOUND_RANGE_EXCEEDED_INT (5) +#define QM_X86_INVALID_OPCODE_INT (6) +#define QM_X86_DEVICE_NOT_AVAILABLE_INT (7) +#define QM_X86_DOUBLE_FAULT_INT (8) +#define QM_X86_INTEL_RESERVED_09_INT (9) +#define QM_X86_INVALID_TSS_INT (10) +#define QM_X86_SEGMENT_NOT_PRESENT_INT (11) +#define QM_X86_STACK_SEGMENT_FAULT_INT (12) +#define QM_X86_GENERAL_PROTECT_FAULT_INT (13) +#define QM_X86_PAGE_FAULT_INT (14) +#define QM_X86_INTEL_RESERVED_15_INT (15) +#define QM_X86_FLOATING_POINT_ERROR_INT (16) +#define QM_X86_ALIGNMENT_CHECK_INT (17) +#define QM_X86_INTEL_RESERVED_18_INT (18) +#define QM_X86_INTEL_RESERVED_19_INT (19) +#define QM_X86_INTEL_RESERVED_20_INT (20) +#define QM_X86_INTEL_RESERVED_21_INT (21) +#define QM_X86_INTEL_RESERVED_22_INT (22) +#define QM_X86_INTEL_RESERVED_23_INT (23) +#define QM_X86_INTEL_RESERVED_24_INT (24) +#define QM_X86_INTEL_RESERVED_25_INT (25) +#define QM_X86_INTEL_RESERVED_26_INT (26) +#define QM_X86_INTEL_RESERVED_27_INT (27) +#define QM_X86_INTEL_RESERVED_28_INT (28) +#define QM_X86_INTEL_RESERVED_29_INT (29) +#define QM_X86_INTEL_RESERVED_30_INT (30) +#define QM_X86_INTEL_RESERVED_31_INT (31) + +#define QM_X86_PIC_TIMER_INT_VECTOR (32) + +#endif /* QM_LAKEMONT */ + +#if (QM_SENSOR) + +/* ARC EM processor internal interrupt vector assignments. */ +#define QM_ARC_RESET_INT (0) +#define QM_ARC_MEMORY_ERROR_INT (1) +#define QM_ARC_INSTRUCTION_ERROR_INT (2) +#define QM_ARC_MACHINE_CHECK_EXCEPTION_INT (3) +#define QM_ARC_INSTRUCTION_TLB_MISS_INT (4) +#define QM_ARC_DATA_TLB_MISS_INT (5) +#define QM_ARC_PROTECTION_VIOLATION_INT (6) +#define QM_ARC_PRIVILEGE_VIOLATION_INT (7) +#define QM_ARC_SOFTWARE_INTERRUPT_INT (8) +#define QM_ARC_TRAP_INT (9) +#define QM_ARC_EXTENSION_INSTRUCTION_EXCEPTION_INT (10) +#define QM_ARC_DIVIDE_BY_ZERO_INT (11) +#define QM_ARC_DATA_CACHE_CONSISTENCY_ERROR_INT (12) +#define QM_ARC_MISALIGNED_DATA_ACCESS_INT (13) +#define QM_ARC_RESERVED_14_INT (14) +#define QM_ARC_RESERVED_15_INT (15) +#define QM_ARC_TIMER_0_INT (16) +#define QM_ARC_TIMER_1_INT (17) + +#endif /* QM_SENSOR */ + +#if (QM_SENSOR) +/** + * Sensor Sub-System Specific IRQs and interrupt vectors. + * + * @name SS Interrupt + * @{ + */ + +#define QM_SS_EXCEPTION_NUM (16) /* Exceptions and traps in ARC EM core. */ +#define QM_SS_INT_TIMER_NUM (2) /* Internal interrupts in ARC EM core. */ +#define QM_SS_IRQ_SENSOR_NUM (18) /* IRQ's from the Sensor Subsystem. */ +#define QM_SS_IRQ_COMMON_NUM (32) /* IRQ's from the common SoC fabric. */ +#define QM_SS_INT_VECTOR_NUM \ + (QM_SS_EXCEPTION_NUM + QM_SS_INT_TIMER_NUM + QM_SS_IRQ_SENSOR_NUM + \ + QM_SS_IRQ_COMMON_NUM) +#define QM_SS_IRQ_NUM (QM_SS_IRQ_SENSOR_NUM + QM_SS_IRQ_COMMON_NUM) + +/* + * The following definitions are Sensor Subsystem interrupt irq and vector + * numbers: + * #define QM_SS_xxx - irq number + * #define QM_SS_xxx_VECTOR - vector number + */ + +/** Sensor Subsystem ADC Rx Fifo Error Interrupt. */ +#define QM_SS_IRQ_ADC_0_ERROR_INT 0 +#define QM_SS_IRQ_ADC_0_ERROR_INT_VECTOR 18 + +/** Sensor Subsystem ADC Data Available Interrupt. */ +#define QM_SS_IRQ_ADC_0_INT 1 +#define QM_SS_IRQ_ADC_0_INT_VECTOR 19 + +/** Sensor Subsystem GPIO Single Interrupt 0 */ +#define QM_SS_IRQ_GPIO_0_INT 2 +#define QM_SS_IRQ_GPIO_0_INT_VECTOR 20 + +/** Sensor Subsystem GPIO Single Interrupt 1. */ +#define QM_SS_IRQ_GPIO_1_INT 3 +#define QM_SS_IRQ_GPIO_1_INT_VECTOR 21 + +/** Sensor Subsystem I2C 0 Error Interrupt. */ +#define QM_SS_IRQ_I2C_0_ERROR_INT 4 +#define QM_SS_IRQ_I2C_0_ERROR_INT_VECTOR 22 + +/** Sensor Subsystem I2C 0 Data Available Interrupt. */ +#define QM_SS_IRQ_I2C_0_RX_AVAIL_INT 5 +#define QM_SS_IRQ_I2C_0_RX_AVAIL_INT_VECTOR 23 + +/** Sensor Subsystem I2C 0 Data Required Interrupt. */ +#define QM_SS_IRQ_I2C_0_TX_REQ_INT 6 +#define QM_SS_IRQ_I2C_0_TX_REQ_INT_VECTOR 24 + +/** Sensor Subsystem I2C 0 Stop Detect Interrupt. */ +#define QM_SS_IRQ_I2C_0_STOP_DET_INT 7 +#define QM_SS_IRQ_I2C_0_STOP_DET_INT_VECTOR 25 + +/** Sensor Subsystem I2C 1 Error Interrupt. */ +#define QM_SS_IRQ_I2C_1_ERROR_INT 8 +#define QM_SS_IRQ_I2C_1_ERROR_INT_VECTOR 26 + +/** Sensor Subsystem I2C 1 Data Available Interrupt. */ +#define QM_SS_IRQ_I2C_1_RX_AVAIL_INT 9 +#define QM_SS_IRQ_I2C_1_RX_AVAIL_INT_VECTOR 27 + +/** Sensor Subsystem I2C 1 Data Required Interrupt. */ +#define QM_SS_IRQ_I2C_1_TX_REQ_INT 10 +#define QM_SS_IRQ_I2C_1_TX_REQ_INT_VECTOR 28 + +/** Sensor Subsystem I2C 1 Stop Detect Interrupt. */ +#define QM_SS_IRQ_I2C_1_STOP_DET_INT 11 +#define QM_SS_IRQ_I2C_1_STOP_DET_INT_VECTOR 29 + +/** Sensor Subsystem SPI 0 Error Interrupt. */ +#define QM_SS_IRQ_SPI_0_ERROR_INT 12 +#define QM_SS_IRQ_SPI_0_ERROR_INT_VECTOR 30 + +/** Sensor Subsystem SPI 0 Data Available Interrupt. */ +#define QM_SS_IRQ_SPI_0_RX_AVAIL_INT 13 +#define QM_SS_IRQ_SPI_0_RX_AVAIL_INT_VECTOR 31 + +/** Sensor Subsystem SPI 0 Data Required Interrupt. */ +#define QM_SS_IRQ_SPI_0_TX_REQ_INT 14 +#define QM_SS_IRQ_SPI_0_TX_REQ_INT_VECTOR 32 + +/** Sensor Subsystem SPI 1 Error Interrupt. */ +#define QM_SS_IRQ_SPI_1_ERROR_INT 15 +#define QM_SS_IRQ_SPI_1_ERROR_INT_VECTOR 33 + +/** Sensor Subsystem SPI 1 Data Available Interrupt. */ +#define QM_SS_IRQ_SPI_1_RX_AVAIL_INT 16 +#define QM_SS_IRQ_SPI_1_RX_AVAIL_INT_VECTOR 34 + +/** Sensor Subsystem SPI 1 Data Required Interrupt. */ +#define QM_SS_IRQ_SPI_1_TX_REQ_INT 17 +#define QM_SS_IRQ_SPI_1_TX_REQ_INT_VECTOR 35 + +typedef enum { + QM_SS_INT_PRIORITY_0 = 0, + QM_SS_INT_PRIORITY_1 = 1, + QM_SS_INT_PRIORITY_15 = 15, + QM_SS_INT_PRIORITY_NUM +} qm_ss_irq_priority_t; + +typedef enum { QM_SS_INT_DISABLE = 0, QM_SS_INT_ENABLE = 1 } qm_ss_irq_mask_t; + +typedef enum { + QM_SS_IRQ_LEVEL_SENSITIVE = 0, + QM_SS_IRQ_EDGE_SENSITIVE = 1 +} qm_ss_irq_trigger_t; + +#define QM_SS_AUX_IRQ_CTRL (0xE) +#define QM_SS_AUX_IRQ_HINT (0x201) +#define QM_SS_AUX_IRQ_PRIORITY (0x206) +#define QM_SS_AUX_IRQ_STATUS (0x406) +#define QM_SS_AUX_IRQ_SELECT (0x40B) +#define QM_SS_AUX_IRQ_ENABLE (0x40C) +#define QM_SS_AUX_IRQ_TRIGGER (0x40D) + +/** @} */ + +#endif /* QM_SENSOR */ + +/** + * @name Common SoC IRQs and Interrupts + * @{ + */ + +/* IRQs and interrupt vectors. + * + * Any IRQ > 1 actually has a event router mask register offset of +1. + * The vector numbers must be defined without arithmetic expressions nor + * parentheses because they are expanded as token concatenation. + */ + +/** I2C Master 0 Single Interrupt. */ +#define QM_IRQ_I2C_0_INT 0 +#define QM_IRQ_I2C_0_INT_MASK_OFFSET 0 +#define QM_IRQ_I2C_0_INT_VECTOR 36 + +/** I2C Master 1 Single Interrupt. */ +#define QM_IRQ_I2C_1_INT 1 +#define QM_IRQ_I2C_1_INT_MASK_OFFSET 1 +#define QM_IRQ_I2C_1_INT_VECTOR 37 + +/** SPI Master 0 Single Interrupt. */ +#define QM_IRQ_SPI_MASTER_0_INT 2 +#define QM_IRQ_SPI_MASTER_0_INT_MASK_OFFSET 3 +#define QM_IRQ_SPI_MASTER_0_INT_VECTOR 38 + +/** SPI Master 1 Single Interrupt. */ +#define QM_IRQ_SPI_MASTER_1_INT 3 +#define QM_IRQ_SPI_MASTER_1_INT_MASK_OFFSET 4 +#define QM_IRQ_SPI_MASTER_1_INT_VECTOR 39 + +/** SPI Slave Single Interrupt. */ +#define QM_IRQ_SPI_SLAVE_0_INT 4 +#define QM_IRQ_SPI_SLAVE_0_INT_MASK_OFFSET 5 +#define QM_IRQ_SPI_SLAVE_0_INT_VECTOR 40 + +/** UART 0 Single Interrupt. */ +#define QM_IRQ_UART_0_INT 5 +#define QM_IRQ_UART_0_INT_MASK_OFFSET 6 +#define QM_IRQ_UART_0_INT_VECTOR 41 + +/** UART 1 Single Interrupt. */ +#define QM_IRQ_UART_1_INT 6 +#define QM_IRQ_UART_1_INT_MASK_OFFSET 7 +#define QM_IRQ_UART_1_INT_VECTOR 42 + +/** I2S Single Interrupt. */ +#define QM_IRQ_I2S_0_INT 7 +#define QM_IRQ_I2S_0_INT_MASK_OFFSET 8 +#define QM_IRQ_I2S_0_INT_VECTOR 43 + +/** GPIO Single Interrupt. */ +#define QM_IRQ_GPIO_0_INT 8 +#define QM_IRQ_GPIO_0_INT_MASK_OFFSET 9 +#define QM_IRQ_GPIO_0_INT_VECTOR 44 + +/** PWM/Timer Single Interrupt. */ +#define QM_IRQ_PWM_0_INT 9 +#define QM_IRQ_PWM_0_INT_MASK_OFFSET 10 +#define QM_IRQ_PWM_0_INT_VECTOR 45 + +/** USB Single Interrupt. */ +#define QM_IRQ_USB_0_INT (10) +#define QM_IRQ_USB_0_INT_MASK_OFFSET (11) +#define QM_IRQ_USB_0_INT_VECTOR 46 + +/** RTC Single Interrupt. */ +#define QM_IRQ_RTC_0_INT 11 +#define QM_IRQ_RTC_0_INT_MASK_OFFSET 12 +#define QM_IRQ_RTC_0_INT_VECTOR 47 + +/** WDT Single Interrupt. */ +#define QM_IRQ_WDT_0_INT 12 +#define QM_IRQ_WDT_0_INT_MASK_OFFSET 13 +#define QM_IRQ_WDT_0_INT_VECTOR 48 + +/** DMA Channel 0 Single Interrupt. */ +#define QM_IRQ_DMA_0_INT_0 13 +#define QM_IRQ_DMA_0_INT_0_MASK_OFFSET 14 +#define QM_IRQ_DMA_0_INT_0_VECTOR 49 + +/** DMA Channel 1 Single Interrupt. */ +#define QM_IRQ_DMA_0_INT_1 14 +#define QM_IRQ_DMA_0_INT_1_MASK_OFFSET 15 +#define QM_IRQ_DMA_0_INT_1_VECTOR 50 + +/** DMA Channel 2 Single Interrupt. */ +#define QM_IRQ_DMA_0_INT_2 15 +#define QM_IRQ_DMA_0_INT_2_MASK_OFFSET 16 +#define QM_IRQ_DMA_0_INT_2_VECTOR 51 + +/** DMA Channel 3 Single Interrupt. */ +#define QM_IRQ_DMA_0_INT_3 16 +#define QM_IRQ_DMA_0_INT_3_MASK_OFFSET 17 +#define QM_IRQ_DMA_0_INT_3_VECTOR 52 + +/** DMA Channel 4 Single Interrupt. */ +#define QM_IRQ_DMA_0_INT_4 17 +#define QM_IRQ_DMA_0_INT_4_MASK_OFFSET 18 +#define QM_IRQ_DMA_0_INT_4_VECTOR 53 + +/** DMA Channel 5 Single Interrupt. */ +#define QM_IRQ_DMA_0_INT_5 18 +#define QM_IRQ_DMA_0_INT_5_MASK_OFFSET 19 +#define QM_IRQ_DMA_0_INT_5_VECTOR 54 + +/** DMA Channel 6 Single Interrupt. */ +#define QM_IRQ_DMA_0_INT_6 19 +#define QM_IRQ_DMA_0_INT_6_MASK_OFFSET 20 +#define QM_IRQ_DMA_0_INT_6_VECTOR 55 + +/** DMA Channel 7 Single Interrupt. */ +#define QM_IRQ_DMA_0_INT_7 20 +#define QM_IRQ_DMA_0_INT_7_MASK_OFFSET 21 +#define QM_IRQ_DMA_0_INT_7_VECTOR 56 + +/** + * 8 Mailbox Channel Interrupts Routed to Single Interrupt + * with 8bit Mask per Destination. + */ +#define QM_IRQ_MAILBOX_0_INT 21 +#define QM_IRQ_MAILBOX_0_INT_MASK_OFFSET 22 +#define QM_IRQ_MAILBOX_0_INT_VECTOR 57 + +/** + * 19 Comparators Routed to Single Interrupt with 19bit Mask per Destination. + */ +#define QM_IRQ_COMPARATOR_0_INT 22 +#define QM_IRQ_COMPARATOR_0_INT_MASK_OFFSET 26 +#define QM_IRQ_COMPARATOR_0_INT_VECTOR 58 + +/** System and Power Management Single Interrupt. */ +#define QM_IRQ_PMU_0_INT 23 +#define QM_IRQ_PMU_0_INT_MASK_OFFSET 26 +#define QM_IRQ_PMU_0_INT_VECTOR 58 + +/** + * 8 DMA Channel Error Interrupts Routed to Single Interrupt with 8bit Mask + * per Destination. + */ +#define QM_IRQ_DMA_0_ERROR_INT 24 +#define QM_IRQ_DMA_0_ERROR_INT_MASK_OFFSET 28 +#define QM_IRQ_DMA_0_ERROR_INT_VECTOR 60 + +/** Internal SRAM Memory Protection Error Single Interrupt. */ +#define QM_IRQ_SRAM_MPR_0_INT 25 +#define QM_IRQ_SRAM_MPR_0_INT_MASK_OFFSET 29 +#define QM_IRQ_SRAM_MPR_0_INT_VECTOR 61 + +/** Internal Flash Controller 0 Memory Protection Error Single Interrupt. */ +#define QM_IRQ_FLASH_MPR_0_INT 26 +#define QM_IRQ_FLASH_MPR_0_INT_MASK_OFFSET 30 +#define QM_IRQ_FLASH_MPR_0_INT_VECTOR 62 + +/** Internal Flash Controller 1 Memory Protection Error Single Interrupt. */ +#define QM_IRQ_FLASH_MPR_1_INT 27 +#define QM_IRQ_FLASH_MPR_1_INT_MASK_OFFSET 31 +#define QM_IRQ_FLASH_MPR_1_INT_VECTOR 63 + +/** Always-On Timer Interrupt. */ +#define QM_IRQ_AONPT_0_INT 28 +#define QM_IRQ_AONPT_0_INT_MASK_OFFSET 32 +#define QM_IRQ_AONPT_0_INT_VECTOR 64 + +/** ADC power sequence done. */ +#define QM_SS_IRQ_ADC_0_PWR_INT 29 +#define QM_SS_IRQ_ADC_0_PWR_INT_MASK_OFFSET 33 +#define QM_SS_IRQ_ADC_0_PWR_INT_VECTOR 65 + +/** ADC calibration done. */ +#define QM_SS_IRQ_ADC_0_CAL_INT 30 +#define QM_SS_IRQ_ADC_0_CAL_INT_MASK_OFFSET 34 +#define QM_SS_IRQ_ADC_0_CAL_INT_VECTOR 66 + +/** Always-On GPIO Interrupt. */ +#define QM_IRQ_AON_GPIO_0_INT 31 +#define QM_IRQ_AON_GPIO_0_INT_MASK_OFFSET 35 +#define QM_IRQ_AON_GPIO_0_INT_VECTOR 67 + +/** @} */ + +/** @} */ + +#endif /* __QM_SOC_INTERRUPTS_H__ */ diff --git a/libraries/CuriePowerManagement/src/qmsi/qm_soc_regs.h b/libraries/CuriePowerManagement/src/qmsi/qm_soc_regs.h new file mode 100644 index 00000000..54887384 --- /dev/null +++ b/libraries/CuriePowerManagement/src/qmsi/qm_soc_regs.h @@ -0,0 +1,2105 @@ +/* + * Copyright (c) 2016, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __REGISTERS_H__ +#define __REGISTERS_H__ + +#include "qm_common.h" +#include "qm_soc_interrupts.h" +#include "qm_interrupt_router_regs.h" + +/** + * Quark SE SoC Registers. + * + * @defgroup groupQUARKSESEREG SoC Registers (SE) + * @{ + */ + +#define QUARK_SE (1) +#define HAS_4_TIMERS (1) +#define HAS_AON_GPIO (1) +#define HAS_MAILBOX (1) +#define HAS_USB (1) + +#if !defined(QM_SENSOR) +#define HAS_APIC (1) +#endif + +/** + * @name System Core + * @{ + */ + +/** System Core register map. */ +typedef struct { + QM_RW uint32_t osc0_cfg0; /**< Hybrid Oscillator Configuration 0. */ + QM_RW uint32_t osc0_stat1; /**< Hybrid Oscillator status 1. */ + QM_RW uint32_t osc0_cfg1; /**< Hybrid Oscillator configuration 1. */ + QM_RW uint32_t osc1_stat0; /**< RTC Oscillator status 0. */ + QM_RW uint32_t osc1_cfg0; /**< RTC Oscillator Configuration 0. */ + QM_RW uint32_t usb_pll_cfg0; /**< USB Phase lock look configuration. */ + QM_RW uint32_t + ccu_periph_clk_gate_ctl; /**< Peripheral Clock Gate Control. */ + QM_RW uint32_t + ccu_periph_clk_div_ctl0; /**< Peripheral Clock Divider Control. 0 */ + QM_RW uint32_t + ccu_gpio_db_clk_ctl; /**< Peripheral Clock Divider Control 1. */ + QM_RW uint32_t + ccu_ext_clock_ctl; /**< External Clock Control Register. */ + /** Sensor Subsystem peripheral clock gate control. */ + QM_RW uint32_t ccu_ss_periph_clk_gate_ctl; + QM_RW uint32_t ccu_lp_clk_ctl; /**< System Low Power Clock Control. */ + QM_RW uint32_t reserved; + QM_RW uint32_t ccu_mlayer_ahb_ctl; /**< AHB Control Register. */ + QM_RW uint32_t ccu_sys_clk_ctl; /**< System Clock Control Register. */ + QM_RW uint32_t osc_lock_0; /**< Clocks Lock Register. */ +} qm_scss_ccu_reg_t; + +#if (UNIT_TEST) +qm_scss_ccu_reg_t test_scss_ccu; +#define QM_SCSS_CCU ((qm_scss_ccu_reg_t *)(&test_scss_ccu)) + +#else +#define QM_SCSS_CCU_BASE (0xB0800000) +#define QM_SCSS_CCU ((qm_scss_ccu_reg_t *)QM_SCSS_CCU_BASE) +#endif + +/* Hybrid oscillator output select select (0=Silicon, 1=Crystal) */ +#define QM_OSC0_MODE_SEL BIT(3) +#define QM_OSC0_PD BIT(2) +#define QM_OSC1_PD BIT(1) + +/* Enable Crystal oscillator. */ +#define QM_OSC0_EN_CRYSTAL BIT(0) + +/* Crystal oscillator parameters. */ +#define OSC0_CFG1_OSC0_FADJ_XTAL_MASK (0x000F0000) +#define OSC0_CFG1_OSC0_FADJ_XTAL_OFFS (16) +#define OSC0_CFG0_OSC0_XTAL_COUNT_VALUE_MASK (0x00600000) +#define OSC0_CFG0_OSC0_XTAL_COUNT_VALUE_OFFS (21) + +/* Silicon Oscillator parameters. */ +#define OSC0_CFG1_FTRIMOTP_MASK (0x3FF00000) +#define OSC0_CFG1_FTRIMOTP_OFFS (20) +#define OSC0_CFG1_SI_FREQ_SEL_MASK (0x00000300) +#define OSC0_CFG1_SI_FREQ_SEL_OFFS (8) + +#define QM_OSC0_MODE_SEL BIT(3) +#define QM_OSC0_LOCK_SI BIT(0) +#define QM_OSC0_LOCK_XTAL BIT(1) +#define QM_OSC0_EN_SI_OSC BIT(1) + +#define QM_SI_OSC_1V2_MODE BIT(0) + +/* Peripheral clock divider control. */ +#define QM_CCU_PERIPH_PCLK_DIV_OFFSET (1) +#define QM_CCU_PERIPH_PCLK_DIV_EN BIT(0) + +/* Clock enable / disable register. */ +#define QM_CCU_MLAYER_AHB_CTL (REG_VAL(0xB0800034)) + +/* System clock control */ +#define QM_CCU_SYS_CLK_SEL BIT(0) +#define QM_SCSS_CCU_SYS_CLK_SEL BIT(0) +#define QM_SCSS_CCU_C2_LP_EN BIT(1) +#define QM_SCSS_CCU_SS_LPS_EN BIT(0) +#define QM_CCU_RTC_CLK_EN BIT(1) +#define QM_CCU_RTC_CLK_DIV_EN BIT(2) +#define QM_CCU_SYS_CLK_DIV_EN BIT(7) +#define QM_CCU_SYS_CLK_DIV_MASK (0x00000300) + +#define QM_OSC0_SI_FREQ_SEL_DEF_MASK (0xFFFFFCFF) +#define QM_CCU_GPIO_DB_DIV_OFFSET (2) +#define QM_CCU_GPIO_DB_CLK_DIV_EN BIT(1) +#define QM_CCU_GPIO_DB_CLK_EN BIT(0) +#define QM_CCU_RTC_CLK_DIV_OFFSET (3) +#define QM_CCU_SYS_CLK_DIV_OFFSET (8) +#define QM_CCU_DMA_CLK_EN BIT(6) + +/** @} */ + +/** + * @name General Purpose + * @{ + */ + +/** General Purpose register map. */ +typedef struct { + QM_RW uint32_t gps0; /**< General Purpose Sticky Register 0 */ + QM_RW uint32_t gps1; /**< General Purpose Sticky Register 1 */ + QM_RW uint32_t gps2; /**< General Purpose Sticky Register 2 */ + QM_RW uint32_t gps3; /**< General Purpose Sticky Register 3 */ + QM_RW uint32_t reserved; + QM_RW uint32_t gp0; /**< General Purpose Scratchpad Register 0 */ + QM_RW uint32_t gp1; /**< General Purpose Scratchpad Register 1 */ + QM_RW uint32_t gp2; /**< General Purpose Scratchpad Register 2 */ + QM_RW uint32_t gp3; /**< General Purpose Scratchpad Register 3 */ + QM_RW uint32_t reserved1; + QM_RW uint32_t id; /**< Identification Register */ + QM_RW uint32_t rev; /**< Revision Register */ + QM_RW uint32_t wo_sp; /**< Write-One-to-Set Scratchpad Register */ + QM_RW uint32_t + wo_st; /**< Write-One-to-Set Sticky Scratchpad Register */ +} qm_scss_gp_reg_t; + +#if (UNIT_TEST) +qm_scss_gp_reg_t test_scss_gp; +#define QM_SCSS_GP ((qm_scss_gp_reg_t *)(&test_scss_gp)) + +#else +#define QM_SCSS_GP_BASE (0xB0800100) +#define QM_SCSS_GP ((qm_scss_gp_reg_t *)QM_SCSS_GP_BASE) +#endif + +/* The GPS0 register usage. */ +#define QM_GPS0_BIT_FM (0) /**< Start Firmware Manager. */ +#define QM_GPS0_BIT_X86_WAKEUP (1) /**< Lakemont core reset type. */ +#define QM_GPS0_BIT_SENSOR_WAKEUP (2) /**< Sensor core reset type. */ + +/** @} */ + +/** + * @name Memory Control + * @{ + */ + +/** Memory Control register map. */ +typedef struct { + QM_RW uint32_t mem_ctrl; /**< Memory control */ +} qm_scss_mem_reg_t; + +#if (UNIT_TEST) +qm_scss_mem_reg_t test_scss_mem; +#define QM_SCSS_MEM ((qm_scss_mem_reg_t *)(&test_scss_mem)) + +#else +#define QM_SCSS_MEM_BASE (0xB0800200) +#define QM_SCSS_MEM ((qm_scss_mem_reg_t *)QM_SCSS_MEM_BASE) +#endif + +/** @} */ + +/** + * @name Comparator + * @{ + */ + +/** Comparator register map. */ +typedef struct { + QM_RW uint32_t cmp_en; /**< Comparator enable. */ + QM_RW uint32_t cmp_ref_sel; /**< Comparator reference select. */ + QM_RW uint32_t + cmp_ref_pol; /**< Comparator reference polarity select register. */ + QM_RW uint32_t cmp_pwr; /**< Comparator power enable register. */ + QM_RW uint32_t reserved[6]; + QM_RW uint32_t cmp_stat_clr; /**< Comparator clear register. */ +} qm_scss_cmp_reg_t; + +#if (UNIT_TEST) +qm_scss_cmp_reg_t test_scss_cmp; +#define QM_SCSS_CMP ((qm_scss_cmp_reg_t *)(&test_scss_cmp)) + +#else +#define QM_SCSS_CMP_BASE (0xB0800300) +#define QM_SCSS_CMP ((qm_scss_cmp_reg_t *)QM_SCSS_CMP_BASE) +#endif + +#define QM_AC_HP_COMPARATORS_MASK (0x7FFC0) + +/** @} */ + +/** + * @name APIC + * @{ + */ + +typedef struct { + QM_RW uint32_t reg; + QM_RW uint32_t pad[3]; +} apic_reg_pad_t; + +/** APIC register block type. */ +typedef struct { + QM_RW apic_reg_pad_t reserved0[2]; + QM_RW apic_reg_pad_t id; /**< LAPIC ID */ + QM_RW apic_reg_pad_t version; /**< LAPIC version*/ + QM_RW apic_reg_pad_t reserved1[4]; + QM_RW apic_reg_pad_t tpr; /**< Task priority*/ + QM_RW apic_reg_pad_t apr; /**< Arbitration priority */ + QM_RW apic_reg_pad_t ppr; /**< Processor priority */ + QM_RW apic_reg_pad_t eoi; /**< End of interrupt */ + QM_RW apic_reg_pad_t rrd; /**< Remote read */ + QM_RW apic_reg_pad_t ldr; /**< Logical destination */ + QM_RW apic_reg_pad_t dfr; /**< Destination format */ + QM_RW apic_reg_pad_t svr; /**< Spurious vector */ + QM_RW apic_reg_pad_t isr[8]; /**< In-service */ + QM_RW apic_reg_pad_t tmr[8]; /**< Trigger mode */ + QM_RW apic_reg_pad_t irr[8]; /**< Interrupt request */ + QM_RW apic_reg_pad_t esr; /**< Error status */ + QM_RW apic_reg_pad_t reserved2[6]; + QM_RW apic_reg_pad_t lvtcmci; /**< Corrected Machine Check vector */ + QM_RW apic_reg_pad_t icr[2]; /**< Interrupt command */ + QM_RW apic_reg_pad_t lvttimer; /**< Timer vector */ + QM_RW apic_reg_pad_t lvtts; /**< Thermal sensor vector */ + QM_RW apic_reg_pad_t lvtpmcr; /**< Perfmon counter vector */ + QM_RW apic_reg_pad_t lvtlint0; /**< Local interrupt 0 vector */ + QM_RW apic_reg_pad_t lvtlint1; /**< Local interrupt 1 vector */ + QM_RW apic_reg_pad_t lvterr; /**< Error vector */ + QM_RW apic_reg_pad_t timer_icr; /**< Timer initial count */ + QM_RW apic_reg_pad_t timer_ccr; /**< Timer current count */ + QM_RW apic_reg_pad_t reserved3[4]; + QM_RW apic_reg_pad_t timer_dcr; /**< Timer divide configuration */ +} qm_lapic_reg_t; + +#if (HAS_APIC) +/* + * The size of IOAPIC redirection table, as returned by _ioapic_get_redtbl_size + * function. + */ +#define QM_IOAPIC_NUM_RTES (32) + +/** + * IRQ context type. + * + * Applications should not modify the content. + * This structure is only intended to be used by + * qm_irq_save_context and qm_irq_restore_context functions. + */ +typedef struct { + /** Redirection Table Entries. */ + uint32_t redtbl_entries[QM_IOAPIC_NUM_RTES]; +} qm_irq_context_t; +#endif + +/** + * PIC TIMER context type. + * + * Applications should not modify the content. + * This structure is only intended to be used by the qm_pic_timer_save_context + * and qm_pic_timer_restore_context functions. + */ +typedef struct { + uint32_t timer_icr; /**< Initial Count Register. */ + uint32_t timer_dcr; /**< Divide Configuration Register. */ + uint32_t lvttimer; /**< Timer Entry in Local Vector Table. */ +} qm_pic_timer_context_t; + +#if (UNIT_TEST) +qm_lapic_reg_t test_lapic; +#define QM_LAPIC ((qm_lapic_reg_t *)(&test_lapic)) + +#else +/* Local APIC. */ +#define QM_LAPIC_BASE (0xFEE00000) +#define QM_LAPIC ((qm_lapic_reg_t *)QM_LAPIC_BASE) +#endif + +#define QM_INT_CONTROLLER QM_LAPIC + +/* + * Quark SE has a HW limitation that prevents a LAPIC EOI from being broadcast + * into IOAPIC. To trigger this manually we must write the vector number being + * serviced into the IOAPIC EOI register. + */ +#if defined(ENABLE_EXTERNAL_ISR_HANDLING) || defined(QM_SENSOR) +#define QM_ISR_EOI(vector) +#else +#define QM_ISR_EOI(vector) \ + do { \ + QM_INT_CONTROLLER->eoi.reg = 0; \ + QM_IOAPIC->eoi.reg = vector; \ + } while (0) +#endif + +typedef struct { + QM_RW apic_reg_pad_t ioregsel; /**< Register selector. */ + QM_RW apic_reg_pad_t iowin; /**< Register window. */ + QM_RW apic_reg_pad_t reserved[2]; + QM_RW apic_reg_pad_t eoi; /**< EOI register. */ +} qm_ioapic_reg_t; + +#define QM_IOAPIC_REG_VER (0x01) /* IOAPIC version. */ +#define QM_IOAPIC_REG_REDTBL (0x10) /* Redirection table base. */ + +#if (UNIT_TEST) +qm_ioapic_reg_t test_ioapic; +#define QM_IOAPIC ((qm_ioapic_reg_t *)(&test_ioapic)) + +#else +/* IO / APIC base address. */ +#define QM_IOAPIC_BASE (0xFEC00000) +#define QM_IOAPIC ((qm_ioapic_reg_t *)QM_IOAPIC_BASE) +#endif + +/** @} */ + +/** + * @name Power Management + * @{ + */ + +/** Power Management register map. */ +typedef struct { + QM_RW uint32_t p_lvl2; /**< Processor level 2 */ + QM_RW uint32_t reserved[4]; + QM_RW uint32_t pm1c; /**< Power management 1 control */ + QM_RW uint32_t reserved1[9]; + QM_RW uint32_t aon_vr; /**< AON Voltage Regulator */ + QM_RW uint32_t plat3p3_vr; /**< Platform 3p3 voltage regulator */ + QM_RW uint32_t plat1p8_vr; /**< Platform 1p8 voltage regulator */ + QM_RW uint32_t host_vr; /**< Host Voltage Regulator */ + QM_RW uint32_t slp_cfg; /**< Sleeping Configuration */ + /** Power Management Network (PMNet) Control and Status */ + QM_RW uint32_t pmnetcs; + QM_RW uint32_t pm_wait; /**< Power Management Wait */ + QM_RW uint32_t reserved2; + QM_RW uint32_t p_sts; /**< Processor Status */ + QM_RW uint32_t reserved3[3]; + QM_RW uint32_t rstc; /**< Reset Control */ + QM_RW uint32_t rsts; /**< Reset Status */ + QM_RW uint32_t reserved4[6]; + QM_RW uint32_t vr_lock; /**< Voltage regulator lock */ + QM_RW uint32_t pm_lock; /**< Power Management Lock */ +} qm_scss_pmu_reg_t; + +#if (UNIT_TEST) +qm_scss_pmu_reg_t test_scss_pmu; +#define QM_SCSS_PMU ((qm_scss_pmu_reg_t *)(&test_scss_pmu)) + +#else +#define QM_SCSS_PMU_BASE (0xB0800504) +#define QM_SCSS_PMU ((qm_scss_pmu_reg_t *)QM_SCSS_PMU_BASE) +#endif + +#define QM_SS_CFG_ARC_RUN_REQ_A BIT(24) +#define QM_P_STS_HALT_INTERRUPT_REDIRECTION BIT(26) +#define QM_P_STS_ARC_HALT BIT(14) + +#define QM_AON_VR_VSEL_MASK (0xFFE0) +#define QM_AON_VR_VSEL_1V2 (0x8) +#define QM_AON_VR_VSEL_1V35 (0xB) +#define QM_AON_VR_VSEL_1V8 (0x10) +#define QM_AON_VR_EN BIT(7) +#define QM_AON_VR_VSTRB BIT(5) + +#define QM_SCSS_SLP_CFG_LPMODE_EN BIT(8) +#define QM_SCSS_SLP_CFG_RTC_DIS BIT(7) +#define QM_SCSS_PM1C_SLPEN BIT(13) +#define QM_SCSS_HOST_VR_EN BIT(7) +#define QM_SCSS_PLAT3P3_VR_EN BIT(7) +#define QM_SCSS_PLAT1P8_VR_EN BIT(7) +#define QM_SCSS_HOST_VR_VREG_SEL BIT(6) +#define QM_SCSS_PLAT3P3_VR_VREG_SEL BIT(6) +#define QM_SCSS_PLAT1P8_VR_VREG_SEL BIT(6) +#define QM_SCSS_VR_ROK BIT(10) +#define QM_SCSS_VR_EN BIT(7) +#define QM_SCSS_VR_VREG_SEL BIT(6) + +/** @} */ + +/** + * @name Sensor Subsystem + * @{ + */ + +/** Sensor Subsystem register map. */ +typedef struct { + QM_RW uint32_t ss_cfg; /**< Sensor Subsystem Configuration */ + QM_RW uint32_t ss_sts; /**< Sensor Subsystem status */ +} qm_scss_ss_reg_t; + +#if (UNIT_TEST) +qm_scss_ss_reg_t test_scss_ss; +#define QM_SCSS_SS ((qm_scss_ss_reg_t *)(&test_scss_ss)) + +#else +#define QM_SCSS_SS_BASE (0xB0800600) +#define QM_SCSS_SS ((qm_scss_ss_reg_t *)QM_SCSS_SS_BASE) +#endif + +#define QM_SS_STS_HALT_INTERRUPT_REDIRECTION BIT(26) + +/** @} */ + +/** + * @name Always-on Counters. + * @{ + */ + +/** Number of Always-on counter controllers. */ +typedef enum { QM_AONC_0 = 0, QM_AONC_NUM } qm_aonc_t; + +/** Always-on Counter Controller register map. */ +typedef struct { + QM_RW uint32_t aonc_cnt; /**< Always-on counter register. */ + QM_RW uint32_t aonc_cfg; /**< Always-on counter enable. */ + QM_RW uint32_t aonpt_cnt; /**< Always-on periodic timer. */ + QM_RW uint32_t + aonpt_stat; /**< Always-on periodic timer status register. */ + QM_RW uint32_t aonpt_ctrl; /**< Always-on periodic timer control. */ + QM_RW uint32_t + aonpt_cfg; /**< Always-on periodic timer configuration register. */ +} qm_aonc_reg_t; + +#if (UNIT_TEST) +qm_aonc_reg_t test_aonc; +#define QM_AONC ((qm_aonc_reg_t *)(&test_aonc)) + +#else +#define QM_AONC_BASE (0xB0800700) +#define QM_AONC ((qm_aonc_reg_t *)QM_AONC_BASE) +#endif + +/** @} */ + +/** + * @name Peripheral Registers + * @{ + */ + +/** Peripheral Registers register map. */ +typedef struct { + QM_RW uint32_t usb_phy_cfg0; /**< USB Configuration */ + QM_RW uint32_t periph_cfg0; /**< Peripheral Configuration */ + QM_RW uint32_t reserved[2]; + QM_RW uint32_t cfg_lock; /**< Configuration Lock */ +} qm_scss_peripheral_reg_t; + +#if (UNIT_TEST) +qm_scss_peripheral_reg_t test_scss_peripheral; +#define QM_SCSS_PERIPHERAL ((qm_scss_peripheral_reg_t *)(&test_scss_peripheral)) + +#else +#define QM_SCSS_PERIPHERAL_BASE (0xB0800800) +#define QM_SCSS_PERIPHERAL ((qm_scss_peripheral_reg_t *)QM_SCSS_PERIPHERAL_BASE) +#endif + +/** @} */ + +/** + * @name Pin MUX + * @{ + */ + +/** Pin MUX register map. */ +typedef struct { + QM_RW uint32_t pmux_pullup[4]; /**< Pin Mux Pullup */ + QM_RW uint32_t pmux_slew[4]; /**< Pin Mux Slew Rate */ + QM_RW uint32_t pmux_in_en[4]; /**< Pin Mux Input Enable */ + QM_RW uint32_t pmux_sel[5]; /**< Pin Mux Select */ + QM_RW uint32_t reserved[2]; + QM_RW uint32_t pmux_pullup_lock; /**< Pin Mux Pullup Lock */ + QM_RW uint32_t pmux_slew_lock; /**< Pin Mux Slew Rate Lock */ + QM_RW uint32_t pmux_sel_lock[3]; /**< Pin Mux Select Lock */ + QM_RW uint32_t pmux_in_en_lock; /**< Pin Mux Slew Rate Lock */ +} qm_scss_pmux_reg_t; + +#if (UNIT_TEST) +qm_scss_pmux_reg_t test_scss_pmux; +#define QM_SCSS_PMUX ((qm_scss_pmux_reg_t *)(&test_scss_pmux)) + +#else +#define QM_SCSS_PMUX_BASE (0xB0800900) +#define QM_SCSS_PMUX ((qm_scss_pmux_reg_t *)QM_SCSS_PMUX_BASE) +#endif + +/* Pin MUX slew rate registers and settings */ +#define QM_PMUX_SLEW_4MA_DRIVER (0xFFFFFFFF) +#define QM_PMUX_SLEW0 (REG_VAL(0xB0800910)) +#define QM_PMUX_SLEW1 (REG_VAL(0xB0800914)) +#define QM_PMUX_SLEW2 (REG_VAL(0xB0800918)) +#define QM_PMUX_SLEW3 (REG_VAL(0xB080091C)) + +/** @} */ + +/** + * @name ID + * @{ + */ + +/** Information register map. */ +typedef struct { + QM_RW uint32_t id; +} qm_scss_info_reg_t; + +#if (UNIT_TEST) +qm_scss_info_reg_t test_scss_info; +#define QM_SCSS_INFO ((qm_scss_info_reg_t *)(&test_scss_info)) + +#else +#define QM_SCSS_INFO_BASE (0xB0801000) +#define QM_SCSS_INFO ((qm_scss_info_reg_t *)QM_SCSS_INFO_BASE) +#endif + +/** @} */ + +/** + * @name Mailbox + * @{ + */ + +#define HAS_MAILBOX (1) +#define NUM_MAILBOXES (8) + +#define HAS_MAILBOX_LAKEMONT_DEST (1) +#define HAS_MAILBOX_SENSOR_SUB_SYSTEM_DEST (1) + +/** + * Mailbox MBOX_CH_CTRL_N Mailbox Channel Control Word Register + * + * 31 RW/1S/V MBOX_CH_CTRL_INT Mailbox Channel Control Word interrupt + * 30:0 RW MBOX_CH_CTRL Mailbox Channel Control Word + */ +#define QM_MBOX_CH_CTRL_INT BIT(31) +#define QM_MBOX_CH_CTRL_MASK (0x7FFFFFFF) +#define QM_MBOX_CH_CTRL_SHIFT (0) + +/* + * Mailbox Channel Status MBOX_CH_STS_N + * + * 31:2 RO reserved + * 1 RW/1C/V MBOX_CH_STS_CTRL_INT Mailbox Channel Interrupt Status + * - Bit set when message sent, indicates pending interrupt + * - Bit set when a mailbox channel interrupt is pending.. + * - Bit cleared by writing 1 + * - Bit should be cleared by the receivers isr + * 0 RW/1C/V MBOX_CH_STS Mailbox Channel Status + * - Bit set when message sent, indicates pending data + * - Bit cleared by writing 1 + * - Bit should be cleared by the receiver after + * consuming the message. + */ +#define QM_MBOX_CH_STS_CTRL_INT BIT(1) +#define QM_MBOX_CH_STS BIT(0) + +#define QM_MBOX_STATUS_MASK (QM_MBOX_CH_STS | QM_MBOX_CH_STS_CTRL_INT) + +/** + * Mailbox MBOX_CHALL_STS Channel Status Bits Register + * + * 31:16 RO reserved + * 15:0 RO/V MBOX_CHALL_STS Channel Status Bits + */ +#define QM_MBOX_CHALL_STS(N) BIT((N * 2)) +#define QM_MBOX_CHALL_INT_STS(N) BIT((N * 2) + 1) + +/** + * Mailbox interrupt routing mask register INT_MAILBOX_MASK + * + * There is only 1 Mailbox interrupt mask register. + * The register contains masks for all 8 mailbox channels. + * + * Note that the Mailbox interrupt mask register does not follow + * the same layout as most other interrupt mask registers in the SCSS. + * + * Mask bit positions for INT_MAILBOX_MASK are listed here: + * + * 31:24 RW/P/L INT_MAILBOX_SS_HALT_MASK Mailbox SS Halt interrupt mask + * 23:16 RW/P/L INT_MAILBOX_HOST_HALT_MASK Mailbox Host Halt interrupt mask + * 15:8 RW/P/L INT_MAILBOX_SS_MASK Mailbox SS interrupt mask + * 7:0 RW/P/L INT_MAILBOX_HOST_MASK Mailbox Host interrupt mask + */ +#define QM_MBOX_SS_HALT_MASK_OFFSET (24) +#define QM_MBOX_SS_HALT_MASK_MASK (0xFF000000) +#define QM_MBOX_HOST_HALT_MASK_OFFSET (16) +#define QM_MBOX_HOST_HALT_MASK_MASK (0x00FF0000) +#define QM_MBOX_SS_MASK_OFFSET (8) +#define QM_MBOX_SS_MASK_MASK (0x0000FF00) +#define QM_MBOX_HOST_MASK_OFFSET (0) +#define QM_MBOX_HOST_MASK_MASK (0x000000FF) + +/** + * Mailbox Interrupt Mask enable/disable definitions + * + * \#defines use the channel number to determine the register and bit shift to + * use. + * The interrupt destination adds an offset to the bit shift. + */ +#define QM_MBOX_ENABLE_LMT_INT_MASK(N) \ + QM_INTERRUPT_ROUTER->mailbox_0_int_mask &= \ + ~(BIT(N + QM_MBOX_HOST_MASK_OFFSET)) +#define QM_MBOX_DISABLE_LMT_INT_MASK(N) \ + QM_INTERRUPT_ROUTER->mailbox_0_int_mask |= \ + (BIT(N + QM_MBOX_HOST_MASK_OFFSET)) +#define QM_MBOX_ENABLE_SS_INT_MASK(N) \ + QM_INTERRUPT_ROUTER->mailbox_0_int_mask &= \ + ~(BIT(N + QM_MBOX_SS_MASK_OFFSET)) +#define QM_MBOX_DISABLE_SS_INT_MASK(N) \ + QM_INTERRUPT_ROUTER->mailbox_0_int_mask |= \ + (BIT(N + QM_MBOX_SS_MASK_OFFSET)) + +/** + * Mailbox Interrupt Halt Mask enable/disable definitions + * + * \#defines use the channel number to determine the register and bit shift to + * use. + * The interrupt destination adds an offset to the bit shift, + * see above for the bit position layout + */ +#define QM_MBOX_ENABLE_LMT_INT_HALT_MASK(N) \ + QM_INTERRUPT_ROUTER->mailbox_0_int_mask &= \ + ~(BIT(N + QM_MBOX_HOST_HALT_MASK_OFFSET)) +#define QM_MBOX_DISABLE_LMT_INT_HALT_MASK(N) \ + QM_INTERRUPT_ROUTER->mailbox_0_int_mask |= \ + (BIT(N + QM_MBOX_HOST_HALT_MASK_OFFSET)) +#define QM_MBOX_ENABLE_SS_INT_HALT_MASK(N) \ + QM_INTERRUPT_ROUTER->mailbox_0_int_mask &= \ + ~(BIT(N + QM_MBOX_SS_HALT_MASK_OFFSET)) +#define QM_MBOX_DISABLE_SS_INT_HALT_MASK(N) \ + QM_INTERRUPT_ROUTER->mailbox_0_int_mask |= \ + (BIT(N + QM_MBOX_SS_HALT_MASK_OFFSET)) + +/** + * Mailbox interrupt mask definitions to return the current mask values + */ +#define QM_MBOX_SS_INT_HALT_MASK \ + ((QM_MBOX_SS_HALT_MASK_MASK & \ + QM_INTERRUPT_ROUTER->mailbox_0_int_mask) >> \ + QM_MBOX_SS_HALT_MASK_OFFSET) +#define QM_MBOX_LMT_INT_HALT_MASK \ + ((QM_MBOX_HOST_HALT_MASK_MASK & \ + QM_INTERRUPT_ROUTER->mailbox_0_int_mask) >> \ + QM_MBOX_SS_HALT_MASK_OFFSET) +#define QM_MBOX_SS_INT_MASK \ + ((QM_MBOX_SS_MASK_MASK & QM_INTERRUPT_ROUTER->mailbox_0_int_mask) >> \ + QM_MBOX_SS_MASK_OFFSET) +#define QM_MBOX_LMT_INT_MASK \ + (QM_MBOX_HOST_MASK_MASK & QM_INTERRUPT_ROUTER->mailbox_0_int_mask) + +/** + * Mailbox interrupt macros to determine if the specified mailbox interrupt mask + * has been locked. + */ +#define QM_MBOX_SS_INT_LOCK_HALT_MASK(N) \ + (QM_INTERRUPT_ROUTER->lock_int_mask_reg & BIT(3)) +#define QM_MBOX_LMT_INT_LOCK_HALT_MASK(N) \ + (QM_INTERRUPT_ROUTER->lock_int_mask_reg & BIT(2)) +#define QM_MBOX_SS_INT_LOCK_MASK(N) \ + (QM_INTERRUPT_ROUTER->lock_int_mask_reg & BIT(1)) +#define QM_MBOX_LMT_INT_LOCK_MASK(N) \ + (QM_INTERRUPT_ROUTER->lock_int_mask_reg & BIT(0)) + +/** Mailbox register structure. */ +typedef struct { + QM_RW uint32_t ch_ctrl; /**< Channel Control Word */ + QM_RW uint32_t ch_data[4]; /**< Channel Payload Data Word 0 */ + QM_RW uint32_t ch_sts; /**< Channel status */ +} qm_mailbox_t; + +/** Mailbox register map. */ +typedef struct { + qm_mailbox_t mbox[NUM_MAILBOXES]; /**< 8 Mailboxes */ + QM_RW uint32_t mbox_chall_sts; /**< All channel status */ +} qm_mailbox_reg_t; + +#if (UNIT_TEST) +qm_mailbox_reg_t test_mailbox; +#define QM_MAILBOX ((qm_mailbox_reg_t *)(&test_mailbox)) + +#else +#define QM_MAILBOX_BASE (0xB0800A00) +#define QM_MAILBOX ((qm_mailbox_reg_t *)QM_MAILBOX_BASE) +#endif + +/** @} */ + +/** + * @name PWM / Timer + * @{ + */ + +/** Number of PWM / Timer controllers. */ +typedef enum { QM_PWM_0 = 0, QM_PWM_NUM } qm_pwm_t; + +/** PWM ID type. */ +typedef enum { + QM_PWM_ID_0 = 0, + QM_PWM_ID_1, + QM_PWM_ID_2, + QM_PWM_ID_3, + QM_PWM_ID_NUM +} qm_pwm_id_t; + +/** PWM / Timer channel register map. */ +typedef struct { + QM_RW uint32_t loadcount; /**< Load Count */ + QM_RW uint32_t currentvalue; /**< Current Value */ + QM_RW uint32_t controlreg; /**< Control */ + QM_RW uint32_t eoi; /**< End Of Interrupt */ + QM_RW uint32_t intstatus; /**< Interrupt Status */ +} qm_pwm_channel_t; + +/** PWM / Timer register map. */ +typedef struct { + qm_pwm_channel_t timer[QM_PWM_ID_NUM]; /**< 4 Timers */ + QM_RW uint32_t reserved[20]; + QM_RW uint32_t timersintstatus; /**< Timers Interrupt Status */ + QM_RW uint32_t timerseoi; /**< Timers End Of Interrupt */ + QM_RW uint32_t timersrawintstatus; /**< Timers Raw Interrupt Status */ + QM_RW uint32_t timerscompversion; /**< Timers Component Version */ + QM_RW uint32_t + timer_loadcount2[QM_PWM_ID_NUM]; /**< Timer Load Count 2 */ +} qm_pwm_reg_t; + +/** + * PWM context type. + * + * Applications should not modify the content. + * This structure is only intended to be used by + * the qm_pwm_save_context and qm_pwm_restore_context functions. + */ +typedef struct { + struct { + uint32_t loadcount; /**< Load Count 1. */ + uint32_t loadcount2; /**< Load Count 2. */ + uint32_t controlreg; /**< Control Register. */ + } channel[QM_PWM_ID_NUM]; +} qm_pwm_context_t; + +#if (UNIT_TEST) +qm_pwm_reg_t test_pwm_t; +#define QM_PWM ((qm_pwm_reg_t *)(&test_pwm_t)) + +#else +/* PWM register base address. */ +#define QM_PWM_BASE (0xB0000800) +/* PWM register block. */ +#define QM_PWM ((qm_pwm_reg_t *)QM_PWM_BASE) +#endif + +#define PWM_START (1) + +#define QM_PWM_CONF_MODE_MASK (0xA) +#define QM_PWM_CONF_INT_EN_MASK (0x4) + +#define QM_PWM_INTERRUPT_MASK_OFFSET (0x2) + +/** + * Timer N Control (TimerNControlReg) + * + * 31:4 RO reserved + * 3 RW Timer PWM + * 1 - PWM Mode + * 0 - Timer Mode + * 2 RW Timer Interrupt Mask, set to 1b to mask interrupt. + * 1 RW Timer Mode + * 1 - user-defined count mode + * 0 - free-running mode + * 0 RW Timer Enable + * 0 - Disable PWM/Timer + * 1 - Enable PWM/Timer + */ + +#define QM_PWM_TIMERNCONTROLREG_TIMER_ENABLE (BIT(0)) +#define QM_PWM_TIMERNCONTROLREG_TIMER_MODE (BIT(1)) +#define QM_PWM_TIMERNCONTROLREG_TIMER_INTERRUPT_MASK (BIT(2)) +#define QM_PWM_TIMERNCONTROLREG_TIMER_PWM (BIT(3)) + +#define QM_PWM_MODE_TIMER_FREE_RUNNING_VALUE (0) +#define QM_PWM_MODE_TIMER_COUNT_VALUE (QM_PWM_TIMERNCONTROLREG_TIMER_MODE) +#define QM_PWM_MODE_PWM_VALUE \ + (QM_PWM_TIMERNCONTROLREG_TIMER_PWM | QM_PWM_TIMERNCONTROLREG_TIMER_MODE) + +/** @} */ + +/** + * @name WDT + * @{ + */ + +/** Number of WDT controllers. */ +typedef enum { QM_WDT_0 = 0, QM_WDT_NUM } qm_wdt_t; + +/** Watchdog timer register map. */ +typedef struct { + QM_RW uint32_t wdt_cr; /**< Control Register */ + QM_RW uint32_t wdt_torr; /**< Timeout Range Register */ + QM_RW uint32_t wdt_ccvr; /**< Current Counter Value Register */ + QM_RW uint32_t wdt_crr; /**< Current Restart Register */ + QM_RW uint32_t wdt_stat; /**< Interrupt Status Register */ + QM_RW uint32_t wdt_eoi; /**< Interrupt Clear Register */ + QM_RW uint32_t wdt_comp_param_5; /**< Component Parameters */ + QM_RW uint32_t wdt_comp_param_4; /**< Component Parameters */ + QM_RW uint32_t wdt_comp_param_3; /**< Component Parameters */ + QM_RW uint32_t wdt_comp_param_2; /**< Component Parameters */ + QM_RW uint32_t + wdt_comp_param_1; /**< Component Parameters Register 1 */ + QM_RW uint32_t wdt_comp_version; /**< Component Version Register */ + QM_RW uint32_t wdt_comp_type; /**< Component Type Register */ +} qm_wdt_reg_t; + +/* + * WDT context type. + * + * Application should not modify the content. + * This structure is only intended to be used by the qm_wdt_save_context and + * qm_wdt_restore_context functions. + */ +typedef struct { + uint32_t wdt_cr; /**< Control Register. */ + uint32_t wdt_torr; /**< Timeout Range Register. */ +} qm_wdt_context_t; + +#if (UNIT_TEST) +qm_wdt_reg_t test_wdt; +#define QM_WDT ((qm_wdt_reg_t *)(&test_wdt)) + +#else +/* WDT register base address. */ +#define QM_WDT_BASE (0xB0000000) + +/* WDT register block. */ +#define QM_WDT ((qm_wdt_reg_t *)QM_WDT_BASE) +#endif + +/* Watchdog enable. */ +#define QM_WDT_CR_WDT_ENABLE (BIT(0)) +/* Watchdog mode. */ +#define QM_WDT_CR_RMOD (BIT(1)) +/* Watchdog mode offset. */ +#define QM_WDT_CR_RMOD_OFFSET (1) +/* Watchdog Timeout Mask. */ +#define QM_WDT_TORR_TOP_MASK (0xF) + +/** + * WDT timeout table (in clock cycles): + * Each table entry corresponds with the value loaded + * into the WDT at the time of a WDT reload for the + * corresponding timeout range register value. + * + * TORR | Timeout (Clock Cycles) + * 0. | 2^16 (65536) + * 1. | 2^17 (131072) + * 2. | 2^18 (262144) + * 3. | 2^19 (524288) + * 4. | 2^20 (1048576) + * 5. | 2^21 (2097152) + * 6. | 2^22 (4194304) + * 7. | 2^23 (8388608) + * 8. | 2^24 (16777216) + * 9. | 2^25 (33554432) + * 10. | 2^26 (67108864) + * 11. | 2^27 (134217728) + * 12. | 2^28 (268435456) + * 13. | 2^29 (536870912) + * 14. | 2^30 (1073741824) + * 15. | 2^31 (2147483648) + */ + +/** @} */ + +/** + * @name UART + * @{ + */ + +/* Break character Bit. */ +#define QM_UART_LCR_BREAK BIT(6) +/* Divisor Latch Access Bit. */ +#define QM_UART_LCR_DLAB BIT(7) + +/* Request to Send Bit. */ +#define QM_UART_MCR_RTS BIT(1) +/* Loopback Enable Bit. */ +#define QM_UART_MCR_LOOPBACK BIT(4) +/* Auto Flow Control Enable Bit. */ +#define QM_UART_MCR_AFCE BIT(5) + +/* FIFO Enable Bit. */ +#define QM_UART_FCR_FIFOE BIT(0) +/* Reset Receive FIFO. */ +#define QM_UART_FCR_RFIFOR BIT(1) +/* Reset Transmit FIFO. */ +#define QM_UART_FCR_XFIFOR BIT(2) + +/* Default FIFO RX & TX Thresholds, half full for both. */ +#define QM_UART_FCR_DEFAULT_TX_RX_THRESHOLD (0xB0) +/* Change TX Threshold to empty, keep RX Threshold to default. */ +#define QM_UART_FCR_TX_0_RX_1_2_THRESHOLD (0x80) + +/* Transmit Holding Register Empty. */ +#define QM_UART_IIR_THR_EMPTY (0x02) +/* Received Data Available. */ +#define QM_UART_IIR_RECV_DATA_AVAIL (0x04) +/* Receiver Line Status. */ +#define QM_UART_IIR_RECV_LINE_STATUS (0x06) +/* Character Timeout. */ +#define QM_UART_IIR_CHAR_TIMEOUT (0x0C) +/* Interrupt ID Mask. */ +#define QM_UART_IIR_IID_MASK (0x0F) + +/* Data Ready Bit. */ +#define QM_UART_LSR_DR BIT(0) +/* Overflow Error Bit. */ +#define QM_UART_LSR_OE BIT(1) +/* Parity Error Bit. */ +#define QM_UART_LSR_PE BIT(2) +/* Framing Error Bit. */ +#define QM_UART_LSR_FE BIT(3) +/* Break Interrupt Bit. */ +#define QM_UART_LSR_BI BIT(4) +/* Transmit Holding Register Empty Bit. */ +#define QM_UART_LSR_THRE BIT(5) +/* Transmitter Empty Bit. */ +#define QM_UART_LSR_TEMT BIT(6) +/* Receiver FIFO Error Bit. */ +#define QM_UART_LSR_RFE BIT(7) + +/* Enable Received Data Available Interrupt. */ +#define QM_UART_IER_ERBFI BIT(0) +/* Enable Transmit Holding Register Empty Interrupt. */ +#define QM_UART_IER_ETBEI BIT(1) +/* Enable Receiver Line Status Interrupt. */ +#define QM_UART_IER_ELSI BIT(2) +/* Programmable THRE Interrupt Mode. */ +#define QM_UART_IER_PTIME BIT(7) + +/* Line Status Errors. */ +#define QM_UART_LSR_ERROR_BITS \ + (QM_UART_LSR_OE | QM_UART_LSR_PE | QM_UART_LSR_FE | QM_UART_LSR_BI) + +/* FIFO Depth. */ +#define QM_UART_FIFO_DEPTH (16) +/* FIFO Half Depth. */ +#define QM_UART_FIFO_HALF_DEPTH (QM_UART_FIFO_DEPTH / 2) + +/* Divisor Latch High Offset. */ +#define QM_UART_CFG_BAUD_DLH_OFFS 16 +/* Divisor Latch Low Offset. */ +#define QM_UART_CFG_BAUD_DLL_OFFS 8 +/* Divisor Latch Fraction Offset. */ +#define QM_UART_CFG_BAUD_DLF_OFFS 0 +/* Divisor Latch High Mask. */ +#define QM_UART_CFG_BAUD_DLH_MASK (0xFF << QM_UART_CFG_BAUD_DLH_OFFS) +/* Divisor Latch Low Mask. */ +#define QM_UART_CFG_BAUD_DLL_MASK (0xFF << QM_UART_CFG_BAUD_DLL_OFFS) +/* Divisor Latch Fraction Mask. */ +#define QM_UART_CFG_BAUD_DLF_MASK (0xFF << QM_UART_CFG_BAUD_DLF_OFFS) + +/* Divisor Latch Packing Helper. */ +#define QM_UART_CFG_BAUD_DL_PACK(dlh, dll, dlf) \ + (dlh << QM_UART_CFG_BAUD_DLH_OFFS | dll << QM_UART_CFG_BAUD_DLL_OFFS | \ + dlf << QM_UART_CFG_BAUD_DLF_OFFS) + +/* Divisor Latch High Unpacking Helper. */ +#define QM_UART_CFG_BAUD_DLH_UNPACK(packed) \ + ((packed & QM_UART_CFG_BAUD_DLH_MASK) >> QM_UART_CFG_BAUD_DLH_OFFS) +/* Divisor Latch Low Unpacking Helper. */ +#define QM_UART_CFG_BAUD_DLL_UNPACK(packed) \ + ((packed & QM_UART_CFG_BAUD_DLL_MASK) >> QM_UART_CFG_BAUD_DLL_OFFS) +/* Divisor Latch Fraction Unpacking Helper. */ +#define QM_UART_CFG_BAUD_DLF_UNPACK(packed) \ + ((packed & QM_UART_CFG_BAUD_DLF_MASK) >> QM_UART_CFG_BAUD_DLF_OFFS) + +/** Number of UART controllers. */ +typedef enum { QM_UART_0 = 0, QM_UART_1, QM_UART_NUM } qm_uart_t; + +/** UART register map. */ +typedef struct { + QM_RW uint32_t rbr_thr_dll; /**< Rx Buffer/ Tx Holding/ Div Latch Low */ + QM_RW uint32_t ier_dlh; /**< Interrupt Enable / Divisor Latch High */ + QM_RW uint32_t iir_fcr; /**< Interrupt Identification / FIFO Control */ + QM_RW uint32_t lcr; /**< Line Control */ + QM_RW uint32_t mcr; /**< MODEM Control */ + QM_RW uint32_t lsr; /**< Line Status */ + QM_RW uint32_t msr; /**< MODEM Status */ + QM_RW uint32_t scr; /**< Scratchpad */ + QM_RW uint32_t reserved[23]; + QM_RW uint32_t usr; /**< UART Status */ + QM_RW uint32_t reserved1[9]; + QM_RW uint32_t htx; /**< Halt Transmission */ + QM_RW uint32_t dmasa; /**< DMA Software Acknowledge */ + QM_RW uint32_t reserved2[5]; + QM_RW uint32_t dlf; /**< Divisor Latch Fraction */ + QM_RW uint32_t padding[0xCF]; /* (0x400 - 0xC4) / 4 */ +} qm_uart_reg_t; + +/** + * UART context to be saved between sleep/resume. + * + * Application should not modify the content. + * This structure is only intended to be used by the qm_uart_save_context and + * qm_uart_restore_context functions. + */ +typedef struct { + uint32_t ier; /**< Interrupt Enable Register. */ + uint32_t dlh; /**< Divisor Latch High. */ + uint32_t dll; /**< Divisor Latch Low. */ + uint32_t lcr; /**< Line Control. */ + uint32_t mcr; /**< Modem Control. */ + uint32_t scr; /**< Scratchpad. */ + uint32_t htx; /**< Halt Transmission. */ + uint32_t dlf; /**< Divisor Latch Fraction. */ +} qm_uart_context_t; + +#if (UNIT_TEST) +qm_uart_reg_t test_uart_instance; +qm_uart_reg_t *test_uart[QM_UART_NUM]; +#define QM_UART test_uart + +#else +/* UART register base address. */ +#define QM_UART_0_BASE (0xB0002000) +#define QM_UART_1_BASE (0xB0002400) +/* UART register block. */ +extern qm_uart_reg_t *qm_uart[QM_UART_NUM]; +#define QM_UART qm_uart +#endif + +/** @} */ + +/** + * @name SPI + * @{ + */ + +/** Number of SPI controllers (only master driver available). */ +typedef enum { QM_SPI_MST_0 = 0, QM_SPI_MST_1, QM_SPI_NUM } qm_spi_t; + +/** SPI register map. */ +typedef struct { + QM_RW uint32_t ctrlr0; /**< Control Register 0 */ + QM_RW uint32_t ctrlr1; /**< Control Register 1 */ + QM_RW uint32_t ssienr; /**< SSI Enable Register */ + QM_RW uint32_t mwcr; /**< Microwire Control Register */ + QM_RW uint32_t ser; /**< Slave Enable Register */ + QM_RW uint32_t baudr; /**< Baud Rate Select */ + QM_RW uint32_t txftlr; /**< Transmit FIFO Threshold Level */ + QM_RW uint32_t rxftlr; /**< Receive FIFO Threshold Level */ + QM_RW uint32_t txflr; /**< Transmit FIFO Level Register */ + QM_RW uint32_t rxflr; /**< Receive FIFO Level Register */ + QM_RW uint32_t sr; /**< Status Register */ + QM_RW uint32_t imr; /**< Interrupt Mask Register */ + QM_RW uint32_t isr; /**< Interrupt Status Register */ + QM_RW uint32_t risr; /**< Raw Interrupt Status Register */ + QM_RW uint32_t txoicr; /**< Tx FIFO Overflow Interrupt Clear Register*/ + QM_RW uint32_t rxoicr; /**< Rx FIFO Overflow Interrupt Clear Register */ + QM_RW uint32_t rxuicr; /**< Rx FIFO Underflow Interrupt Clear Register*/ + QM_RW uint32_t msticr; /**< Multi-Master Interrupt Clear Register */ + QM_RW uint32_t icr; /**< Interrupt Clear Register */ + QM_RW uint32_t dmacr; /**< DMA Control Register */ + QM_RW uint32_t dmatdlr; /**< DMA Transmit Data Level */ + QM_RW uint32_t dmardlr; /**< DMA Receive Data Level */ + QM_RW uint32_t idr; /**< Identification Register */ + QM_RW uint32_t ssi_comp_version; /**< coreKit Version ID register */ + QM_RW uint32_t dr[36]; /**< Data Register */ + QM_RW uint32_t rx_sample_dly; /**< RX Sample Delay Register */ + QM_RW uint32_t padding[0xC4]; /* (0x400 - 0xF0) / 4 */ +} qm_spi_reg_t; + +/** + * SPI context type. + * + * Applications should not modify the content. + * This structure is only intended to be used by + * the qm_spi_save_context and qm_spi_restore_context functions. + */ +typedef struct { + uint32_t ctrlr0; /**< Control Register 0. */ + uint32_t ser; /**< Slave Enable Register. */ + uint32_t baudr; /**< Baud Rate Select. */ +} qm_spi_context_t; + +#if (UNIT_TEST) +qm_spi_reg_t test_spi; +qm_spi_reg_t *test_spi_controllers[QM_SPI_NUM]; + +#define QM_SPI test_spi_controllers + +#else +/* SPI Master register base address. */ +#define QM_SPI_MST_0_BASE (0xB0001000) +#define QM_SPI_MST_1_BASE (0xB0001400) +extern qm_spi_reg_t *qm_spi_controllers[QM_SPI_NUM]; +#define QM_SPI qm_spi_controllers + +/* SPI Slave register base address. */ +#define QM_SPI_SLV_BASE (0xB0001800) +#endif + +/* SPI Ctrlr0 register. */ +#define QM_SPI_CTRLR0_DFS_32_MASK (0x001F0000) +#define QM_SPI_CTRLR0_TMOD_MASK (0x00000300) +#define QM_SPI_CTRLR0_SCPOL_SCPH_MASK (0x000000C0) +#define QM_SPI_CTRLR0_FRF_MASK (0x00000030) +#define QM_SPI_CTRLR0_DFS_32_OFFSET (16) +#define QM_SPI_CTRLR0_TMOD_OFFSET (8) +#define QM_SPI_CTRLR0_SCPOL_SCPH_OFFSET (6) +#define QM_SPI_CTRLR0_FRF_OFFSET (4) + +/* SPI SSI Enable register. */ +#define QM_SPI_SSIENR_SSIENR BIT(0) + +/* SPI Status register. */ +#define QM_SPI_SR_BUSY BIT(0) +#define QM_SPI_SR_TFNF BIT(1) +#define QM_SPI_SR_TFE BIT(2) +#define QM_SPI_SR_RFNE BIT(3) +#define QM_SPI_SR_RFF BIT(4) + +/* SPI Interrupt Mask register. */ +#define QM_SPI_IMR_MASK_ALL (0x00) +#define QM_SPI_IMR_TXEIM BIT(0) +#define QM_SPI_IMR_TXOIM BIT(1) +#define QM_SPI_IMR_RXUIM BIT(2) +#define QM_SPI_IMR_RXOIM BIT(3) +#define QM_SPI_IMR_RXFIM BIT(4) + +/* SPI Interrupt Status register. */ +#define QM_SPI_ISR_TXEIS BIT(0) +#define QM_SPI_ISR_TXOIS BIT(1) +#define QM_SPI_ISR_RXUIS BIT(2) +#define QM_SPI_ISR_RXOIS BIT(3) +#define QM_SPI_ISR_RXFIS BIT(4) + +/* SPI Raw Interrupt Status register. */ +#define QM_SPI_RISR_TXEIR BIT(0) +#define QM_SPI_RISR_TXOIR BIT(1) +#define QM_SPI_RISR_RXUIR BIT(2) +#define QM_SPI_RISR_RXOIR BIT(3) +#define QM_SPI_RISR_RXFIR BIT(4) + +/* SPI DMA control. */ +#define QM_SPI_DMACR_RDMAE BIT(0) +#define QM_SPI_DMACR_TDMAE BIT(1) + +/** @} */ + +/** + * @name RTC + * @{ + */ + +/** Number of RTC controllers. */ +typedef enum { QM_RTC_0 = 0, QM_RTC_NUM } qm_rtc_t; + +/** RTC register map. */ +typedef struct { + QM_RW uint32_t rtc_ccvr; /**< Current Counter Value Register */ + QM_RW uint32_t rtc_cmr; /**< Current Match Register */ + QM_RW uint32_t rtc_clr; /**< Counter Load Register */ + QM_RW uint32_t rtc_ccr; /**< Counter Control Register */ + QM_RW uint32_t rtc_stat; /**< Interrupt Status Register */ + QM_RW uint32_t rtc_rstat; /**< Interrupt Raw Status Register */ + QM_RW uint32_t rtc_eoi; /**< End of Interrupt Register */ + QM_RW uint32_t rtc_comp_version; /**< End of Interrupt Register */ +} qm_rtc_reg_t; + +#define QM_RTC_CCR_INTERRUPT_ENABLE BIT(0) +#define QM_RTC_CCR_INTERRUPT_MASK BIT(1) +#define QM_RTC_CCR_ENABLE BIT(2) + +#if (UNIT_TEST) +qm_rtc_reg_t test_rtc; +#define QM_RTC ((qm_rtc_reg_t *)(&test_rtc)) + +#else +/* RTC register base address. */ +#define QM_RTC_BASE (0xB0000400) + +/* RTC register block. */ +#define QM_RTC ((qm_rtc_reg_t *)QM_RTC_BASE) +#endif + +/** @} */ + +/** + * @name I2C + * @{ + */ + +/** Number of I2C controllers. */ +typedef enum { QM_I2C_0 = 0, QM_I2C_1, QM_I2C_NUM } qm_i2c_t; + +/** I2C register map. */ +typedef struct { + QM_RW uint32_t ic_con; /**< Control Register */ + QM_RW uint32_t ic_tar; /**< Master Target Address */ + QM_RW uint32_t ic_sar; /**< Slave Address */ + QM_RW uint32_t ic_hs_maddr; /**< High Speed Master ID */ + QM_RW uint32_t ic_data_cmd; /**< Data Buffer and Command */ + QM_RW uint32_t + ic_ss_scl_hcnt; /**< Standard Speed Clock SCL High Count */ + QM_RW uint32_t + ic_ss_scl_lcnt; /**< Standard Speed Clock SCL Low Count */ + QM_RW uint32_t ic_fs_scl_hcnt; /**< Fast Speed Clock SCL High Count */ + QM_RW uint32_t + ic_fs_scl_lcnt; /**< Fast Speed I2C Clock SCL Low Count */ + QM_RW uint32_t + ic_hs_scl_hcnt; /**< High Speed I2C Clock SCL High Count */ + QM_RW uint32_t + ic_hs_scl_lcnt; /**< High Speed I2C Clock SCL Low Count */ + QM_RW uint32_t ic_intr_stat; /**< Interrupt Status */ + QM_RW uint32_t ic_intr_mask; /**< Interrupt Mask */ + QM_RW uint32_t ic_raw_intr_stat; /**< Raw Interrupt Status */ + QM_RW uint32_t ic_rx_tl; /**< Receive FIFO Threshold Level */ + QM_RW uint32_t ic_tx_tl; /**< Transmit FIFO Threshold Level */ + QM_RW uint32_t + ic_clr_intr; /**< Clear Combined and Individual Interrupt */ + QM_RW uint32_t ic_clr_rx_under; /**< Clear RX_UNDER Interrupt */ + QM_RW uint32_t ic_clr_rx_over; /**< Clear RX_OVER Interrupt */ + QM_RW uint32_t ic_clr_tx_over; /**< Clear TX_OVER Interrupt */ + QM_RW uint32_t ic_clr_rd_req; /**< Clear RD_REQ Interrupt */ + QM_RW uint32_t ic_clr_tx_abrt; /**< Clear TX_ABRT Interrupt */ + QM_RW uint32_t ic_clr_rx_done; /**< Clear RX_DONE Interrupt */ + QM_RW uint32_t ic_clr_activity; /**< Clear ACTIVITY Interrupt */ + QM_RW uint32_t ic_clr_stop_det; /**< Clear STOP_DET Interrupt */ + QM_RW uint32_t ic_clr_start_det; /**< Clear START_DET Interrupt */ + QM_RW uint32_t ic_clr_gen_call; /**< Clear GEN_CALL Interrupt */ + QM_RW uint32_t ic_enable; /**< Enable */ + QM_RW uint32_t ic_status; /**< Status */ + QM_RW uint32_t ic_txflr; /**< Transmit FIFO Level */ + QM_RW uint32_t ic_rxflr; /**< Receive FIFO Level */ + QM_RW uint32_t ic_sda_hold; /**< SDA Hold */ + QM_RW uint32_t ic_tx_abrt_source; /**< Transmit Abort Source */ + QM_RW uint32_t reserved; + QM_RW uint32_t ic_dma_cr; /**< SDA Setup */ + QM_RW uint32_t ic_dma_tdlr; /**< DMA Transmit Data Level Register */ + QM_RW uint32_t ic_dma_rdlr; /**< I2C Receive Data Level Register */ + QM_RW uint32_t ic_sda_setup; /**< SDA Setup */ + QM_RW uint32_t ic_ack_general_call; /**< General Call Ack */ + QM_RW uint32_t ic_enable_status; /**< Enable Status */ + QM_RW uint32_t ic_fs_spklen; /**< SS and FS Spike Suppression Limit */ + QM_RW uint32_t ic_hs_spklen; /**< HS spike suppression limit */ + QM_RW uint32_t reserved1[19]; + QM_RW uint32_t ic_comp_param_1; /**< Configuration Parameters */ + QM_RW uint32_t ic_comp_version; /**< Component Version */ + QM_RW uint32_t ic_comp_type; /**< Component Type */ + QM_RW uint32_t padding[0xC0]; /* Padding (0x400-0xFC)/4 */ +} qm_i2c_reg_t; + +/** + * I2C context to be saved between sleep/resume. + * + * Application should not modify the content. + * This structure is only intended to be used by the qm_i2c_save_context and + * qm_i2c_restore_context functions. + */ +typedef struct { + uint32_t con; /**< Control Register. */ + uint32_t sar; /**< Slave Address. */ + uint32_t ss_scl_hcnt; /**< Standard Speed Clock SCL High Count. */ + uint32_t ss_scl_lcnt; /**< Standard Speed Clock SCL Low Count. */ + uint32_t fs_scl_hcnt; /**< Fast Speed Clock SCL High Count. */ + uint32_t fs_scl_lcnt; /**< Fast Speed I2C Clock SCL Low Count. */ + uint32_t enable; /**< Enable. */ + uint32_t fs_spklen; /**< SS and FS Spike Suppression Limit. */ + uint32_t ic_intr_mask; /**< I2C Interrupt Mask. */ +} qm_i2c_context_t; + +#if (UNIT_TEST) +qm_i2c_reg_t test_i2c_instance[QM_I2C_NUM]; +qm_i2c_reg_t *test_i2c[QM_I2C_NUM]; + +#define QM_I2C test_i2c + +#else +/* I2C Master register base address. */ +#define QM_I2C_0_BASE (0xB0002800) +#define QM_I2C_1_BASE (0xB0002C00) + +/** I2C register block. */ +extern qm_i2c_reg_t *qm_i2c[QM_I2C_NUM]; +#define QM_I2C qm_i2c +#endif + +#define QM_I2C_IC_ENABLE_CONTROLLER_EN BIT(0) +#define QM_I2C_IC_ENABLE_CONTROLLER_ABORT BIT(1) +#define QM_I2C_IC_ENABLE_STATUS_IC_EN BIT(0) +#define QM_I2C_IC_CON_MASTER_MODE BIT(0) +#define QM_I2C_IC_CON_SLAVE_DISABLE BIT(6) +#define QM_I2C_IC_CON_10BITADDR_MASTER BIT(4) +#define QM_I2C_IC_CON_10BITADDR_MASTER_OFFSET (4) +#define QM_I2C_IC_CON_10BITADDR_SLAVE BIT(3) +#define QM_I2C_IC_CON_10BITADDR_SLAVE_OFFSET (3) +#define QM_I2C_IC_CON_SPEED_OFFSET (1) +#define QM_I2C_IC_CON_SPEED_SS BIT(1) +#define QM_I2C_IC_CON_SPEED_FS_FSP BIT(2) +#define QM_I2C_IC_CON_SPEED_MASK (0x06) +#define QM_I2C_IC_CON_RESTART_EN BIT(5) +#define QM_I2C_IC_CON_STOP_DET_IFADDRESSED BIT(7) +#define QM_I2C_IC_DATA_CMD_READ BIT(8) +#define QM_I2C_IC_DATA_CMD_STOP_BIT_CTRL BIT(9) +#define QM_I2C_IC_DATA_CMD_LSB_MASK (0x000000FF) +#define QM_I2C_IC_RAW_INTR_STAT_RX_FULL BIT(2) +#define QM_I2C_IC_RAW_INTR_STAT_TX_ABRT BIT(6) +#define QM_I2C_IC_RAW_INTR_STAT_GEN_CALL BIT(11) +#define QM_I2C_IC_RAW_INTR_STAT_RESTART_DETECTED BIT(12) +#define QM_I2C_IC_TX_ABRT_SOURCE_NAK_MASK (0x1F) +#define QM_I2C_IC_TX_ABRT_SOURCE_ARB_LOST BIT(12) +#define QM_I2C_IC_TX_ABRT_SOURCE_ABRT_SBYTE_NORSTRT BIT(9) +#define QM_I2C_IC_TX_ABRT_SOURCE_ALL_MASK (0x1FFFF) +#define QM_I2C_IC_STATUS_BUSY_MASK (0x00000060) +#define QM_I2C_IC_STATUS_RFF BIT(4) +#define QM_I2C_IC_STATUS_RFNE BIT(3) +#define QM_I2C_IC_STATUS_TFE BIT(2) +#define QM_I2C_IC_STATUS_TNF BIT(1) +#define QM_I2C_IC_INTR_MASK_ALL (0x00) +#define QM_I2C_IC_INTR_MASK_RX_UNDER BIT(0) +#define QM_I2C_IC_INTR_MASK_RX_OVER BIT(1) +#define QM_I2C_IC_INTR_MASK_RX_FULL BIT(2) +#define QM_I2C_IC_INTR_MASK_TX_OVER BIT(3) +#define QM_I2C_IC_INTR_MASK_TX_EMPTY BIT(4) +#define QM_I2C_IC_INTR_MASK_RD_REQ BIT(5) +#define QM_I2C_IC_INTR_MASK_TX_ABORT BIT(6) +#define QM_I2C_IC_INTR_MASK_RX_DONE BIT(7) +#define QM_I2C_IC_INTR_MASK_ACTIVITY BIT(8) +#define QM_I2C_IC_INTR_MASK_STOP_DETECTED BIT(9) +#define QM_I2C_IC_INTR_MASK_START_DETECTED BIT(10) +#define QM_I2C_IC_INTR_MASK_GEN_CALL_DETECTED BIT(11) +#define QM_I2C_IC_INTR_MASK_RESTART_DETECTED BIT(12) +#define QM_I2C_IC_INTR_STAT_RX_UNDER BIT(0) +#define QM_I2C_IC_INTR_STAT_RX_OVER BIT(1) +#define QM_I2C_IC_INTR_STAT_RX_FULL BIT(2) +#define QM_I2C_IC_INTR_STAT_TX_OVER BIT(3) +#define QM_I2C_IC_INTR_STAT_TX_EMPTY BIT(4) +#define QM_I2C_IC_INTR_STAT_RD_REQ BIT(5) +#define QM_I2C_IC_INTR_STAT_TX_ABRT BIT(6) +#define QM_I2C_IC_INTR_STAT_RX_DONE BIT(7) +#define QM_I2C_IC_INTR_STAT_STOP_DETECTED BIT(9) +#define QM_I2C_IC_INTR_STAT_START_DETECTED BIT(10) +#define QM_I2C_IC_INTR_STAT_GEN_CALL_DETECTED BIT(11) +#define QM_I2C_IC_LCNT_MAX (65525) +#define QM_I2C_IC_LCNT_MIN (8) +#define QM_I2C_IC_HCNT_MAX (65525) +#define QM_I2C_IC_HCNT_MIN (6) + +#define QM_I2C_FIFO_SIZE (16) + +/* I2C DMA */ +#define QM_I2C_IC_DMA_CR_RX_ENABLE BIT(0) +#define QM_I2C_IC_DMA_CR_TX_ENABLE BIT(1) + +/** @} */ + +/** + * @name GPIO + * @{ + */ + +/** Number of GPIO controllers. */ +typedef enum { QM_GPIO_0 = 0, QM_AON_GPIO_0 = 1, QM_GPIO_NUM } qm_gpio_t; + +/** GPIO register map. */ +typedef struct { + QM_RW uint32_t gpio_swporta_dr; /**< Port A Data */ + QM_RW uint32_t gpio_swporta_ddr; /**< Port A Data Direction */ + QM_RW uint32_t gpio_swporta_ctl; /**< Port A Data Source */ + QM_RW uint32_t reserved[9]; + QM_RW uint32_t gpio_inten; /**< Interrupt Enable */ + QM_RW uint32_t gpio_intmask; /**< Interrupt Mask */ + QM_RW uint32_t gpio_inttype_level; /**< Interrupt Type */ + QM_RW uint32_t gpio_int_polarity; /**< Interrupt Polarity */ + QM_RW uint32_t gpio_intstatus; /**< Interrupt Status */ + QM_RW uint32_t gpio_raw_intstatus; /**< Raw Interrupt Status */ + QM_RW uint32_t gpio_debounce; /**< Debounce Enable */ + QM_RW uint32_t gpio_porta_eoi; /**< Clear Interrupt */ + QM_RW uint32_t gpio_ext_porta; /**< Port A External Port */ + QM_RW uint32_t reserved1[3]; + QM_RW uint32_t gpio_ls_sync; /**< Synchronization Level */ + QM_RW uint32_t reserved2; + QM_RW uint32_t gpio_int_bothedge; /**< Interrupt both edge type */ + QM_RW uint32_t reserved3; + QM_RW uint32_t gpio_config_reg2; /**< GPIO Configuration Register 2 */ + QM_RW uint32_t gpio_config_reg1; /**< GPIO Configuration Register 1 */ +} qm_gpio_reg_t; + +/** + * GPIO context type. + * + * Application should not modify the content. + * This structure is only intended to be used by the qm_gpio_save_context and + * qm_gpio_restore_context functions. + */ +typedef struct { + uint32_t gpio_swporta_dr; /**< Port A Data. */ + uint32_t gpio_swporta_ddr; /**< Port A Data Direction. */ + uint32_t gpio_swporta_ctl; /**< Port A Data Source. */ + uint32_t gpio_inten; /**< Interrupt Enable. */ + uint32_t gpio_intmask; /**< Interrupt Mask. */ + uint32_t gpio_inttype_level; /**< Interrupt Type. */ + uint32_t gpio_int_polarity; /**< Interrupt Polarity. */ + uint32_t gpio_debounce; /**< Debounce Enable. */ + uint32_t gpio_ls_sync; /**< Synchronization Level. */ + uint32_t gpio_int_bothedge; /**< Interrupt both edge type. */ +} qm_gpio_context_t; + +#define QM_NUM_GPIO_PINS (32) +#define QM_NUM_AON_GPIO_PINS (6) + +#if (UNIT_TEST) +qm_gpio_reg_t test_gpio_instance; +qm_gpio_reg_t *test_gpio[QM_GPIO_NUM]; + +#define QM_GPIO test_gpio +#else + +/* GPIO register base address */ +#define QM_GPIO_BASE (0xB0000C00) +#define QM_AON_GPIO_BASE (QM_SCSS_CCU_BASE + 0xB00) + +/** GPIO register block */ +extern qm_gpio_reg_t *qm_gpio[QM_GPIO_NUM]; +#define QM_GPIO qm_gpio +#endif + +/** @} */ + +/** + * @name Flash + * @{ + */ + +/** Number of Flash controllers. */ +typedef enum { QM_FLASH_0 = 0, QM_FLASH_1, QM_FLASH_NUM } qm_flash_t; + +/** Flash register map. */ +typedef struct { + QM_RW uint32_t tmg_ctrl; /**< TMG_CTRL. */ + QM_RW uint32_t rom_wr_ctrl; /**< ROM_WR_CTRL. */ + QM_RW uint32_t rom_wr_data; /**< ROM_WR_DATA. */ + QM_RW uint32_t flash_wr_ctrl; /**< FLASH_WR_CTRL. */ + QM_RW uint32_t flash_wr_data; /**< FLASH_WR_DATA. */ + QM_RW uint32_t flash_stts; /**< FLASH_STTS. */ + QM_RW uint32_t ctrl; /**< CTRL. */ + QM_RW uint32_t fpr_rd_cfg[4]; /**< 4 FPR_RD_CFG registers. */ + QM_RW uint32_t + mpr_wr_cfg; /**< Flash Write Protection Control Register. */ + QM_RW uint32_t mpr_vsts; /**< Protection Status Register. */ +} qm_flash_reg_t; + +/** + * Flash context type. + * + * Applications should not modify the content. + * This structure is only intended to be used by the + * qm_flash_save_context and qm_flash_restore_context functions. + */ +typedef struct { + /** Flash Timing Control Register. */ + uint32_t tmg_ctrl; + /** Control Register. */ + uint32_t ctrl; +} qm_flash_context_t; + +#if (UNIT_TEST) +qm_flash_reg_t test_flash_instance; +qm_flash_reg_t *test_flash[QM_FLASH_NUM]; +uint8_t test_flash_page[0x800]; + +#define QM_FLASH test_flash + +#define QM_FLASH_REGION_SYS_1_BASE (test_flash_page) +#define QM_FLASH_REGION_SYS_0_BASE (test_flash_page) +#define QM_FLASH_REGION_OTP_0_BASE (test_flash_page) + +#define QM_FLASH_PAGE_MASK (0xCFF) +#define QM_FLASH_MAX_ADDR (0xFFFFFFFF) +#else + +/* Flash physical address mappings */ + +#define QM_FLASH_REGION_SYS_1_BASE (0x40030000) +#define QM_FLASH_REGION_SYS_0_BASE (0x40000000) +#define QM_FLASH_REGION_OTP_0_BASE (0xFFFFE000) + +#define QM_FLASH_PAGE_MASK (0x3F800) +#define QM_FLASH_MAX_ADDR (0x30000) + +/* Flash controller register base address. */ +#define QM_FLASH_BASE_0 (0xB0100000) +#define QM_FLASH_BASE_1 (0xB0200000) + +/* Flash controller register block. */ +extern qm_flash_reg_t *qm_flash[QM_FLASH_NUM]; +#define QM_FLASH qm_flash + +#endif + +#define QM_FLASH_REGION_DATA_BASE_OFFSET (0x00) +#define QM_FLASH_MAX_WAIT_STATES (0xF) +#define QM_FLASH_MAX_US_COUNT (0x3F) +#define QM_FLASH_MAX_PAGE_NUM \ + (QM_FLASH_MAX_ADDR / (4 * QM_FLASH_PAGE_SIZE_DWORDS)) +#define QM_FLASH_CLK_SLOW BIT(14) +#define QM_FLASH_LVE_MODE BIT(5) + +/* Flash mask to clear timing. */ +#define QM_FLASH_TMG_DEF_MASK (0xFFFFFC00) +/* Flash mask to clear micro seconds. */ +#define QM_FLASH_MICRO_SEC_COUNT_MASK (0x3F) +/* Flash mask to clear wait state. */ +#define QM_FLASH_WAIT_STATE_MASK (0x3C0) +/* Flash wait state offset bit. */ +#define QM_FLASH_WAIT_STATE_OFFSET (6) +/* Flash write disable offset bit. */ +#define QM_FLASH_WRITE_DISABLE_OFFSET (4) +/* Flash write disable value. */ +#define QM_FLASH_WRITE_DISABLE_VAL BIT(4) + +/* Flash page erase request. */ +#define ER_REQ BIT(1) +/* Flash page erase done. */ +#define ER_DONE (1) +/* Flash page write request. */ +#define WR_REQ (1) +/* Flash page write done. */ +#define WR_DONE BIT(1) + +/* Flash write address offset. */ +#define WR_ADDR_OFFSET (2) +/* Flash perform mass erase includes OTP region. */ +#define MASS_ERASE_INFO BIT(6) +/* Flash perform mass erase. */ +#define MASS_ERASE BIT(7) + +#define QM_FLASH_ADDRESS_MASK (0x7FF) +/* Increment by 4 bytes each time, but there is an offset of 2, so 0x10. */ +#define QM_FLASH_ADDR_INC (0x10) + +/* Flash page size in dwords. */ +#define QM_FLASH_PAGE_SIZE_DWORDS (0x200) +/* Flash page size in bytes. */ +#define QM_FLASH_PAGE_SIZE_BYTES (0x800) +/* Flash page size in bits. */ +#define QM_FLASH_PAGE_SIZE_BITS (11) + +/** @} */ + +/** + * @name Flash Protection Region + * @{ + */ + +/** + * FPR register map. + */ +typedef enum { + QM_FPR_0, /**< FPR 0. */ + QM_FPR_1, /**< FPR 1. */ + QM_FPR_2, /**< FPR 2. */ + QM_FPR_3, /**< FPR 3. */ + QM_FPR_NUM +} qm_fpr_id_t; + +/** + * FPR context type. + * + * Applications should not modify the content. + * This structure is only intended to be used by the + * qm_fpr_save_context and qm_fpr_restore_context functions. + */ +typedef struct { + /** Flash Protection Region Read Control Register. */ + uint32_t fpr_rd_cfg[QM_FPR_NUM]; +} qm_fpr_context_t; + +/** @} */ + +/** + * @name Memory Protection Region + * @{ + */ + +/* MPR identifier */ +typedef enum { + QM_MPR_0 = 0, /**< Memory Protection Region 0. */ + QM_MPR_1, /**< Memory Protection Region 1. */ + QM_MPR_2, /**< Memory Protection Region 2. */ + QM_MPR_3, /**< Memory Protection Region 3. */ + QM_MPR_NUM /**< Number of Memory Protection Regions. */ +} qm_mpr_id_t; + +/** Memory Protection Region register map. */ +typedef struct { + QM_RW uint32_t mpr_cfg[4]; /**< MPR CFG */ + QM_RW uint32_t mpr_vdata; /**< MPR_VDATA */ + QM_RW uint32_t mpr_vsts; /**< MPR_VSTS */ +} qm_mpr_reg_t; + +/** + * MPR context type. + * + * Application should not modify the content. + * This structure is only intended to be used by the qm_mpr_save_context and + * qm_mpr_restore_context functions. + */ +typedef struct { + uint32_t mpr_cfg[QM_MPR_NUM]; /**< MPR Configuration Register. */ +} qm_mpr_context_t; + +#if (UNIT_TEST) +qm_mpr_reg_t test_mpr; + +#define QM_MPR ((qm_mpr_reg_t *)(&test_mpr)) + +#else + +#define QM_MPR_BASE (0xB0400000) +#define QM_MPR ((qm_mpr_reg_t *)QM_MPR_BASE) + +#endif + +#define QM_MPR_RD_EN_OFFSET (20) +#define QM_MPR_RD_EN_MASK 0x700000 +#define QM_MPR_WR_EN_OFFSET (24) +#define QM_MPR_WR_EN_MASK 0x7000000 +#define QM_MPR_EN_LOCK_OFFSET (30) +#define QM_MPR_EN_LOCK_MASK 0xC0000000 +#define QM_MPR_UP_BOUND_OFFSET (10) +#define QM_MPR_VSTS_VALID BIT(31) +/** @} */ + +#define QM_OSC0_PD BIT(2) + +#define QM_CCU_EXTERN_DIV_OFFSET (3) +#define QM_CCU_EXT_CLK_DIV_EN BIT(2) + +/** + * @name Peripheral Clock + * @{ + */ + +/** Peripheral clock type. */ +typedef enum { + CLK_PERIPH_REGISTER = BIT(0), /**< Peripheral Clock Gate Enable. */ + CLK_PERIPH_CLK = BIT(1), /**< Peripheral Clock Enable. */ + CLK_PERIPH_I2C_M0 = BIT(2), /**< I2C Master 0 Clock Enable. */ + CLK_PERIPH_I2C_M1 = BIT(3), /**< I2C Master 1 Clock Enable. */ + CLK_PERIPH_SPI_S = BIT(4), /**< SPI Slave Clock Enable. */ + CLK_PERIPH_SPI_M0 = BIT(5), /**< SPI Master 0 Clock Enable. */ + CLK_PERIPH_SPI_M1 = BIT(6), /**< SPI Master 1 Clock Enable. */ + CLK_PERIPH_GPIO_INTERRUPT = BIT(7), /**< GPIO Interrupt Clock Enable. */ + CLK_PERIPH_GPIO_DB = BIT(8), /**< GPIO Debounce Clock Enable. */ + CLK_PERIPH_I2S = BIT(9), /**< I2S Clock Enable. */ + CLK_PERIPH_WDT_REGISTER = BIT(10), /**< Watchdog Clock Enable. */ + CLK_PERIPH_RTC_REGISTER = BIT(11), /**< RTC Clock Gate Enable. */ + CLK_PERIPH_PWM_REGISTER = BIT(12), /**< PWM Clock Gate Enable. */ + CLK_PERIPH_GPIO_REGISTER = BIT(13), /**< GPIO Clock Gate Enable. */ + CLK_PERIPH_SPI_M0_REGISTER = + BIT(14), /**< SPI Master 0 Clock Gate Enable. */ + CLK_PERIPH_SPI_M1_REGISTER = + BIT(15), /**< SPI Master 1 Clock Gate Enable. */ + CLK_PERIPH_SPI_S_REGISTER = + BIT(16), /**< SPI Slave Clock Gate Enable. */ + CLK_PERIPH_UARTA_REGISTER = BIT(17), /**< UARTA Clock Gate Enable. */ + CLK_PERIPH_UARTB_REGISTER = BIT(18), /**< UARTB Clock Gate Enable. */ + CLK_PERIPH_I2C_M0_REGISTER = + BIT(19), /**< I2C Master 0 Clock Gate Enable. */ + CLK_PERIPH_I2C_M1_REGISTER = + BIT(20), /**< I2C Master 1 Clock Gate Enable. */ + CLK_PERIPH_I2S_REGISTER = BIT(21), /**< I2S Clock Gate Enable. */ + CLK_PERIPH_ALL = 0x3FFFFF /**< Quark SE peripherals Mask. */ +} clk_periph_t; + +/* Default mask values */ +#define CLK_EXTERN_DIV_DEF_MASK (0xFFFFFFE3) +#define CLK_SYS_CLK_DIV_DEF_MASK (0xFFFFFC7F) +#define CLK_RTC_DIV_DEF_MASK (0xFFFFFF83) +#define CLK_GPIO_DB_DIV_DEF_MASK (0xFFFFFFE1) +#define CLK_PERIPH_DIV_DEF_MASK (0xFFFFFFF9) + +/** @} */ + +/** + * @name DMA + * @{ + */ + +/** DMA instances. */ +typedef enum { + QM_DMA_0, /**< DMA controller id. */ + QM_DMA_NUM /**< Number of DMA controllers. */ +} qm_dma_t; + +/** DMA channel IDs. */ +typedef enum { + QM_DMA_CHANNEL_0 = 0, /**< DMA channel id for channel 0 */ + QM_DMA_CHANNEL_1, /**< DMA channel id for channel 1 */ + QM_DMA_CHANNEL_2, /**< DMA channel id for channel 2 */ + QM_DMA_CHANNEL_3, /**< DMA channel id for channel 3 */ + QM_DMA_CHANNEL_4, /**< DMA channel id for channel 4 */ + QM_DMA_CHANNEL_5, /**< DMA channel id for channel 5 */ + QM_DMA_CHANNEL_6, /**< DMA channel id for channel 6 */ + QM_DMA_CHANNEL_7, /**< DMA channel id for channel 7 */ + QM_DMA_CHANNEL_NUM /**< Number of DMA channels */ +} qm_dma_channel_id_t; + +/** DMA hardware handshake interfaces. */ +typedef enum { + DMA_HW_IF_UART_A_TX = 0x0, /**< UART_A_TX */ + DMA_HW_IF_UART_A_RX = 0x1, /**< UART_A_RX */ + DMA_HW_IF_UART_B_TX = 0x2, /**< UART_B_TX*/ + DMA_HW_IF_UART_B_RX = 0x3, /**< UART_B_RX */ + DMA_HW_IF_SPI_MASTER_0_TX = 0x4, /**< SPI_Master_0_TX */ + DMA_HW_IF_SPI_MASTER_0_RX = 0x5, /**< SPI_Master_0_RX */ + DMA_HW_IF_SPI_MASTER_1_TX = 0x6, /**< SPI_Master_1_TX */ + DMA_HW_IF_SPI_MASTER_1_RX = 0x7, /**< SPI_Master_1_RX */ + DMA_HW_IF_SPI_SLAVE_TX = 0x8, /**< SPI_Slave_TX */ + DMA_HW_IF_SPI_SLAVE_RX = 0x9, /**< SPI_Slave_RX */ + DMA_HW_IF_I2S_PLAYBACK = 0xa, /**< I2S_Playback channel */ + DMA_HW_IF_I2S_CAPTURE = 0xb, /**< I2S_Capture channel */ + DMA_HW_IF_I2C_MASTER_0_TX = 0xc, /**< I2C_Master_0_TX */ + DMA_HW_IF_I2C_MASTER_0_RX = 0xd, /**< I2C_Master_0_RX */ + DMA_HW_IF_I2C_MASTER_1_TX = 0xe, /**< I2C_Master_1_TX */ + DMA_HW_IF_I2C_MASTER_1_RX = 0xf, /**< I2C_Master_1_RX */ +} qm_dma_handshake_interface_t; + +/** DMA channel register map. */ +typedef struct { + QM_RW uint32_t sar_low; /**< SAR */ + QM_RW uint32_t sar_high; /**< SAR */ + QM_RW uint32_t dar_low; /**< DAR */ + QM_RW uint32_t dar_high; /**< DAR */ + QM_RW uint32_t llp_low; /**< LLP */ + QM_RW uint32_t llp_high; /**< LLP */ + QM_RW uint32_t ctrl_low; /**< CTL */ + QM_RW uint32_t ctrl_high; /**< CTL */ + QM_RW uint32_t src_stat_low; /**< SSTAT */ + QM_RW uint32_t src_stat_high; /**< SSTAT */ + QM_RW uint32_t dst_stat_low; /**< DSTAT */ + QM_RW uint32_t dst_stat_high; /**< DSTAT */ + QM_RW uint32_t src_stat_addr_low; /**< SSTATAR */ + QM_RW uint32_t src_stat_addr_high; /**< SSTATAR */ + QM_RW uint32_t dst_stat_addr_low; /**< DSTATAR */ + QM_RW uint32_t dst_stat_addr_high; /**< DSTATAR */ + QM_RW uint32_t cfg_low; /**< CFG */ + QM_RW uint32_t cfg_high; /**< CFG */ + QM_RW uint32_t src_sg_low; /**< SGR */ + QM_RW uint32_t src_sg_high; /**< SGR */ + QM_RW uint32_t dst_sg_low; /**< DSR */ + QM_RW uint32_t dst_sg_high; /**< DSR */ +} qm_dma_chan_reg_t; + +/* DMA channel control register offsets and masks. */ +#define QM_DMA_CTL_L_INT_EN_MASK BIT(0) +#define QM_DMA_CTL_L_DST_TR_WIDTH_OFFSET (1) +#define QM_DMA_CTL_L_DST_TR_WIDTH_MASK (0x7 << QM_DMA_CTL_L_DST_TR_WIDTH_OFFSET) +#define QM_DMA_CTL_L_SRC_TR_WIDTH_OFFSET (4) +#define QM_DMA_CTL_L_SRC_TR_WIDTH_MASK (0x7 << QM_DMA_CTL_L_SRC_TR_WIDTH_OFFSET) +#define QM_DMA_CTL_L_DINC_OFFSET (7) +#define QM_DMA_CTL_L_DINC_MASK (0x3 << QM_DMA_CTL_L_DINC_OFFSET) +#define QM_DMA_CTL_L_SINC_OFFSET (9) +#define QM_DMA_CTL_L_SINC_MASK (0x3 << QM_DMA_CTL_L_SINC_OFFSET) +#define QM_DMA_CTL_L_DEST_MSIZE_OFFSET (11) +#define QM_DMA_CTL_L_DEST_MSIZE_MASK (0x7 << QM_DMA_CTL_L_DEST_MSIZE_OFFSET) +#define QM_DMA_CTL_L_SRC_MSIZE_OFFSET (14) +#define QM_DMA_CTL_L_SRC_MSIZE_MASK (0x7 << QM_DMA_CTL_L_SRC_MSIZE_OFFSET) +#define QM_DMA_CTL_L_TT_FC_OFFSET (20) +#define QM_DMA_CTL_L_TT_FC_MASK (0x7 << QM_DMA_CTL_L_TT_FC_OFFSET) +#define QM_DMA_CTL_L_LLP_DST_EN_MASK BIT(27) +#define QM_DMA_CTL_L_LLP_SRC_EN_MASK BIT(28) +#define QM_DMA_CTL_H_BLOCK_TS_OFFSET (0) +#define QM_DMA_CTL_H_BLOCK_TS_MASK (0xfff << QM_DMA_CTL_H_BLOCK_TS_OFFSET) +#define QM_DMA_CTL_H_BLOCK_TS_MAX 4095 +#define QM_DMA_CTL_H_BLOCK_TS_MIN 1 + +/* DMA channel config register offsets and masks. */ +#define QM_DMA_CFG_L_CH_SUSP_MASK BIT(8) +#define QM_DMA_CFG_L_FIFO_EMPTY_MASK BIT(9) +#define QM_DMA_CFG_L_HS_SEL_DST_OFFSET 10 +#define QM_DMA_CFG_L_HS_SEL_DST_MASK BIT(QM_DMA_CFG_L_HS_SEL_DST_OFFSET) +#define QM_DMA_CFG_L_HS_SEL_SRC_OFFSET 11 +#define QM_DMA_CFG_L_HS_SEL_SRC_MASK BIT(QM_DMA_CFG_L_HS_SEL_SRC_OFFSET) +#define QM_DMA_CFG_L_DST_HS_POL_OFFSET 18 +#define QM_DMA_CFG_L_DST_HS_POL_MASK BIT(QM_DMA_CFG_L_DST_HS_POL_OFFSET) +#define QM_DMA_CFG_L_SRC_HS_POL_OFFSET 19 +#define QM_DMA_CFG_L_SRC_HS_POL_MASK BIT(QM_DMA_CFG_L_SRC_HS_POL_OFFSET) +#define QM_DMA_CFG_L_RELOAD_SRC_MASK BIT(30) +#define QM_DMA_CFG_L_RELOAD_DST_MASK BIT(31) +#define QM_DMA_CFG_H_DS_UPD_EN_OFFSET (5) +#define QM_DMA_CFG_H_DS_UPD_EN_MASK BIT(QM_DMA_CFG_H_DS_UPD_EN_OFFSET) +#define QM_DMA_CFG_H_SS_UPD_EN_OFFSET (6) +#define QM_DMA_CFG_H_SS_UPD_EN_MASK BIT(QM_DMA_CFG_H_SS_UPD_EN_OFFSET) +#define QM_DMA_CFG_H_SRC_PER_OFFSET (7) +#define QM_DMA_CFG_H_SRC_PER_MASK (0xf << QM_DMA_CFG_H_SRC_PER_OFFSET) +#define QM_DMA_CFG_H_DEST_PER_OFFSET (11) +#define QM_DMA_CFG_H_DEST_PER_MASK (0xf << QM_DMA_CFG_H_DEST_PER_OFFSET) + +/** DMA interrupt register map. */ +typedef struct { + QM_RW uint32_t raw_tfr_low; /**< RawTfr */ + QM_RW uint32_t raw_tfr_high; /**< RawTfr */ + QM_RW uint32_t raw_block_low; /**< RawBlock */ + QM_RW uint32_t raw_block_high; /**< RawBlock */ + QM_RW uint32_t raw_src_trans_low; /**< RawSrcTran */ + QM_RW uint32_t raw_src_trans_high; /**< RawSrcTran */ + QM_RW uint32_t raw_dst_trans_low; /**< RawDstTran */ + QM_RW uint32_t raw_dst_trans_high; /**< RawDstTran */ + QM_RW uint32_t raw_err_low; /**< RawErr */ + QM_RW uint32_t raw_err_high; /**< RawErr */ + QM_RW uint32_t status_tfr_low; /**< StatusTfr */ + QM_RW uint32_t status_tfr_high; /**< StatusTfr */ + QM_RW uint32_t status_block_low; /**< StatusBlock */ + QM_RW uint32_t status_block_high; /**< StatusBlock */ + QM_RW uint32_t status_src_trans_low; /**< StatusSrcTran */ + QM_RW uint32_t status_src_trans_high; /**< StatusSrcTran */ + QM_RW uint32_t status_dst_trans_low; /**< StatusDstTran */ + QM_RW uint32_t status_dst_trans_high; /**< StatusDstTran */ + QM_RW uint32_t status_err_low; /**< StatusErr */ + QM_RW uint32_t status_err_high; /**< StatusErr */ + QM_RW uint32_t mask_tfr_low; /**< MaskTfr */ + QM_RW uint32_t mask_tfr_high; /**< MaskTfr */ + QM_RW uint32_t mask_block_low; /**< MaskBlock */ + QM_RW uint32_t mask_block_high; /**< MaskBlock */ + QM_RW uint32_t mask_src_trans_low; /**< MaskSrcTran */ + QM_RW uint32_t mask_src_trans_high; /**< MaskSrcTran */ + QM_RW uint32_t mask_dst_trans_low; /**< MaskDstTran */ + QM_RW uint32_t mask_dst_trans_high; /**< MaskDstTran */ + QM_RW uint32_t mask_err_low; /**< MaskErr */ + QM_RW uint32_t mask_err_high; /**< MaskErr */ + QM_RW uint32_t clear_tfr_low; /**< ClearTfr */ + QM_RW uint32_t clear_tfr_high; /**< ClearTfr */ + QM_RW uint32_t clear_block_low; /**< ClearBlock */ + QM_RW uint32_t clear_block_high; /**< ClearBlock */ + QM_RW uint32_t clear_src_trans_low; /**< ClearSrcTran */ + QM_RW uint32_t clear_src_trans_high; /**< ClearSrcTran */ + QM_RW uint32_t clear_dst_trans_low; /**< ClearDstTran */ + QM_RW uint32_t clear_dst_trans_high; /**< ClearDstTran */ + QM_RW uint32_t clear_err_low; /**< ClearErr */ + QM_RW uint32_t clear_err_high; /**< ClearErr */ + QM_RW uint32_t status_int_low; /**< StatusInt */ + QM_RW uint32_t status_int_high; /**< StatusInt */ +} qm_dma_int_reg_t; + +/* DMA interrupt status register bits. */ +#define QM_DMA_INT_STATUS_TFR BIT(0) +#define QM_DMA_INT_STATUS_BLOCK BIT(1) +#define QM_DMA_INT_STATUS_ERR BIT(4) + +/** DMA miscellaneous register map. */ +typedef struct { + QM_RW uint32_t cfg_low; /**< DmaCfgReg */ + QM_RW uint32_t cfg_high; /**< DmaCfgReg */ + QM_RW uint32_t chan_en_low; /**< ChEnReg */ + QM_RW uint32_t chan_en_high; /**< ChEnReg */ + QM_RW uint32_t id_low; /**< DmaIdReg */ + QM_RW uint32_t id_high; /**< DmaIdReg */ + QM_RW uint32_t test_low; /**< DmaTestReg */ + QM_RW uint32_t test_high; /**< DmaTestReg */ + QM_RW uint32_t reserved[4]; /**< Reserved */ +} qm_dma_misc_reg_t; + +/* Channel write enable in the misc channel enable register. */ +#define QM_DMA_MISC_CHAN_EN_WE_OFFSET (8) + +/* Controller enable bit in the misc config register. */ +#define QM_DMA_MISC_CFG_DMA_EN BIT(0) + +typedef struct { + QM_RW qm_dma_chan_reg_t chan_reg[8]; /**< Channel Register */ + QM_RW qm_dma_int_reg_t int_reg; /**< Interrupt Register */ + QM_RW uint32_t reserved[12]; /**< Reserved (SW HS) */ + QM_RW qm_dma_misc_reg_t misc_reg; /**< Miscellaneous Register */ +} qm_dma_reg_t; + +/** + * DMA context type. + * + * Applications should not modify the content. + * This structure is only intended to be used by + * the qm_dma_save_context and qm_dma_restore_context functions. + */ +typedef struct { + struct { + uint32_t ctrl_low; /**< Channel Control Lower. */ + uint32_t cfg_low; /**< Channel Configuration Lower. */ + uint32_t cfg_high; /**< Channel Configuration Upper. */ + uint32_t llp_low; /**< Channel Linked List Pointer. */ + } channel[QM_DMA_CHANNEL_NUM]; + uint32_t misc_cfg_low; /**< DMA Configuration. */ +} qm_dma_context_t; + +#if (UNIT_TEST) +qm_dma_reg_t test_dma_instance[QM_DMA_NUM]; +qm_dma_reg_t *test_dma[QM_DMA_NUM]; +#define QM_DMA test_dma +#else +#define QM_DMA_BASE (0xB0700000) +extern qm_dma_reg_t *qm_dma[QM_DMA_NUM]; +#define QM_DMA qm_dma +#endif + +/** @} */ + +/** + * @name USB + * @{ + */ + +#define QM_USB_EP_DIR_IN_MASK (0x80) +#define QM_USB_IN_EP_NUM (6) +#define QM_USB_OUT_EP_NUM (4) +#define QM_USB_MAX_PACKET_SIZE (64) + +/** Number of USB controllers. */ +typedef enum { QM_USB_0 = 0, QM_USB_NUM } qm_usb_t; + +typedef enum { + QM_USB_IN_EP_0 = 0, + QM_USB_IN_EP_1 = 1, + QM_USB_IN_EP_2 = 2, + QM_USB_IN_EP_3 = 3, + QM_USB_IN_EP_4 = 4, + QM_USB_IN_EP_5 = 5, + QM_USB_OUT_EP_0 = 6, + QM_USB_OUT_EP_1 = 7, + QM_USB_OUT_EP_2 = 8, + QM_USB_OUT_EP_3 = 9 +} qm_usb_ep_idx_t; + +/** USB register map. */ + +/** IN Endpoint Registers. */ +typedef struct { + QM_RW uint32_t diepctl; + QM_R uint32_t reserved; + QM_RW uint32_t diepint; + QM_R uint32_t reserved1; + QM_RW uint32_t dieptsiz; + QM_RW uint32_t diepdma; + QM_RW uint32_t dtxfsts; + QM_R uint32_t reserved2; +} qm_usb_in_ep_reg_t; + +/** OUT Endpoint Registers. */ +typedef struct { + QM_RW uint32_t doepctl; + QM_R uint32_t reserved; + QM_RW uint32_t doepint; + QM_R uint32_t reserved1; + QM_RW uint32_t doeptsiz; + QM_RW uint32_t doepdma; + QM_R uint32_t reserved2[2]; +} qm_usb_out_ep_reg_t; + +/** + * USB Register block type. + */ +typedef struct { + QM_RW uint32_t gotgctl; /**< OTG Control. */ + QM_RW uint32_t gotgint; /**< OTG Interrupt. */ + QM_RW uint32_t gahbcfg; /**< AHB Configuration. */ + QM_RW uint32_t gusbcfg; /**< USB Configuration. */ + QM_RW uint32_t grstctl; /**< Reset Register. */ + QM_RW uint32_t gintsts; /**< Interrupt Status. */ + QM_RW uint32_t gintmsk; /**< Interrupt Mask. */ + QM_R uint32_t grxstsr; /**< Receive Status Read/Pop. */ + QM_R uint32_t grxstsp; /**< Receive Status Read/Pop. */ + QM_R uint32_t grxfsiz; /**< Receive FIFO Size. */ + QM_R uint32_t gnptxfsiz; /**< Non-periodic Transmit FIFO Size. */ + QM_R uint32_t reserved[5]; + QM_R uint32_t gsnpsid; /**< Synopsys ID. */ + QM_R uint32_t ghwcfg1; /**< HW config - Endpoint direction. */ + QM_R uint32_t ghwcfg2; /**< HW config 2. */ + QM_R uint32_t ghwcfg3; /**< HW config 3. */ + QM_R uint32_t ghwcfg4; /**< HW config 4. */ + QM_RW uint32_t gdfifocfg; /**< Global DFIFO Configuration. */ + QM_R uint32_t reserved1[43]; + QM_RW uint32_t dieptxf1; + QM_RW uint32_t dieptxf2; + QM_RW uint32_t dieptxf3; + QM_RW uint32_t dieptxf4; + QM_RW uint32_t dieptxf5; + QM_R uint32_t reserved2[442]; + QM_RW uint32_t dcfg; /**< Device config. */ + QM_RW uint32_t dctl; /**< Device control. */ + QM_RW uint32_t dsts; /**< Device Status. */ + QM_R uint32_t reserved3; + QM_RW uint32_t diepmsk; /**< IN EP Common Interrupt Mask. */ + QM_RW uint32_t doepmsk; /**< OUT EP Common Interrupt Mask. */ + QM_R uint32_t daint; /**< Device Interrupt Register. */ + QM_RW uint32_t daintmsk; /**< Device Interrupt Mask Register. */ + QM_R uint32_t reserved4[2]; + QM_RW uint32_t dvbusdis; /**< VBUS discharge time register. */ + QM_RW uint32_t dvbuspulse; /**< Device VBUS discharge time. */ + QM_RW uint32_t dthrctl; /**< Device Threshold Ctrl. */ + QM_RW uint32_t diepempmsk; /**< IN EP FIFO Empty Intr Mask. */ + QM_R uint32_t reserved5[50]; + qm_usb_in_ep_reg_t in_ep_reg[QM_USB_IN_EP_NUM]; + QM_R uint32_t reserved6[80]; + qm_usb_out_ep_reg_t out_ep_reg[QM_USB_OUT_EP_NUM]; +} qm_usb_reg_t; + +#if (UNIT_TEST) +qm_usb_reg_t test_usb; +#define QM_USB ((qm_usb_reg_t *)(&test_usb)) +#else +#define QM_USB_0_BASE (0xB0500000) +/* USB controller base address */ +#define QM_USB ((qm_usb_reg_t *)QM_USB_0_BASE) +#endif + +/* USB PLL enable bit */ +#define QM_USB_PLL_PDLD BIT(0) +/* USB PLL has locked when this bit is 1 */ +#define QM_USB_PLL_LOCK BIT(14) +/* Default values to setup the USB PLL */ +#define QM_USB_PLL_CFG0_DEFAULT (0x00001904) + +/* USB PLL register */ +#if (UNIT_TEST) +uint32_t test_usb_pll; +#define QM_USB_PLL_CFG0 (test_usb_pll) +#else +#define QM_USB_PLL_CFG0 (REG_VAL(0xB0800014)) +#endif + +/* USB clock enable bit */ +#define QM_CCU_USB_CLK_EN BIT(1) + +/** @} */ + +/** + * @name Hardware Fixes + * @{ + */ + +/* Refer to "HARDWARE_ISSUES.rst" for fix description. */ +#define FIX_1 (1) + +/** @} */ + +/** + * @name Versioning + * @{ + */ + +#if (UNIT_TEST) +uint32_t test_rom_version; +#define ROM_VERSION_ADDRESS &test_rom_version; +#else +#define ROM_VERSION_ADDRESS (0xFFFFFFEC); +#endif + +/** @} */ + +/** @} */ + +#endif /* __REGISTERS_H__ */ diff --git a/libraries/CuriePowerManagement/src/qmsi/ss_power_states.h b/libraries/CuriePowerManagement/src/qmsi/ss_power_states.h new file mode 100644 index 00000000..f4dd80b9 --- /dev/null +++ b/libraries/CuriePowerManagement/src/qmsi/ss_power_states.h @@ -0,0 +1,295 @@ +/* + * Copyright (c) 2016, Intel Corporation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of the Intel Corporation nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __QM_SS_POWER_STATES_H__ +#define __QM_SS_POWER_STATES_H__ + +#include "qm_sensor_regs.h" + +/** + * SS Power mode control for Quark SE Microcontrollers. + * + * @defgroup groupSSPower SS Power states + * @{ + */ + +/** + * Sensor Subsystem SS1 Timers mode type. + */ +typedef enum { + SS_POWER_CPU_SS1_TIMER_OFF = 0, /**< Disable SS Timers in SS1. */ + SS_POWER_CPU_SS1_TIMER_ON /**< Keep SS Timers enabled in SS1. */ +} ss_power_cpu_ss1_mode_t; + +/** + * Enable LPSS state entry. + * + * Put the SoC into LPSS on next C2/C2LP and SS2 state combination.
+ * This function needs to be called on the Sensor Core to + * Clock Gate ADC, I2C0, I2C1, SPI0 and SPI1 sensor peripherals.
+ * Clock Gating sensor peripherals is a requirement to enter LPSS state.
+ * After LPSS, ss_power_soc_lpss_disable needs to be called to + * restore clock gating.
+ * + * This needs to be called before any transition to C2/C2LP and SS2 + * in order to enter LPSS.
+ * SoC Hybrid Clock is gated in this state.
+ * Core Well Clocks are gated.
+ * RTC is the only clock running. + * + * Possible SoC wake events are: + * - Low Power Comparator Interrupt + * - AON GPIO Interrupt + * - AON Timer Interrupt + * - RTC Interrupt + */ +//void ss_power_soc_lpss_enable(void); + +/** + * Enter SoC sleep state and restore after wake up. + * + * Put the ARC core into sleep state until next SoC wake event + * and continue execution after wake up where the application stopped. + * + * If the library is built with ENABLE_RESTORE_CONTEXT=1, then this function + * will use the arc_restore_addr to save restore trap address which brings back + * the ARC CPU to the point where this function was called. + * This means that applications should refrain from using them. + * + * This function calls qm_ss_save_context and qm_ss_restore_context + * in order to restore execution where it stopped. + * All power management transitions are done by power_soc_sleep(). + */ +//void ss_power_soc_sleep_restore(void); +/** + * Enter SoC sleep state and restore after wake up. + * + * Put the ARC core into sleep state until next SoC wake event + * and continue execution after wake up where the application stopped. + * + * If the library is built with ENABLE_RESTORE_CONTEXT=1, then this function + * will use the arc_restore_addr to save restore trap address which brings back + * the ARC CPU to the point where this function was called. + * This means that applications should refrain from using them. + * + * This function calls qm_ss_save_context and qm_ss_restore_context + * in order to restore execution where it stopped. + * All power management transitions are done by power_soc_deep_sleep(). + */ +//void ss_power_soc_deep_sleep_restore(void); + +/** + * Save context, enter ARC SS1 power save state and restore after wake up. + * + * This routine is same as ss_power_soc_sleep_restore(), just instead of + * going to sleep it will go to SS1 power save state. + * Note: this function has a while(1) which will spin until we enter + * (and exit) sleep and the power state change will be managed by the other + * core. + */ +//void ss_power_sleep_wait(void); + +/** + * Enable the SENSOR startup restore flag. + */ +//void power_soc_set_ss_restore_flag(void); + +/** + * Disable LPSS state entry. + * + * Clear LPSS enable flag.
+ * Disable Clock Gating of ADC, I2C0, I2C1, SPI0 and SPI1 sensor + * peripherals.
+ * This will prevent entry in LPSS when cores are in C2/C2LP and SS2 states. + */ +//void ss_power_soc_lpss_disable(void); + +/** + * Enter Sensor SS1 state. + * + * Put the Sensor Subsystem into SS1.
+ * Processor Clock is gated in this state. + * + * A wake event causes the Sensor Subsystem to transition to SS0.
+ * A wake event is a sensor subsystem interrupt. + * + * According to the mode selected, Sensor Subsystem Timers can be disabled. + * + * @param[in] mode Mode selection for SS1 state. + */ +//void ss_power_cpu_ss1(const ss_power_cpu_ss1_mode_t mode); + +/** + * Enter Sensor SS2 state or SoC LPSS state. + * + * Put the Sensor Subsystem into SS2.
+ * Sensor Complex Clock is gated in this state.
+ * Sensor Peripherals are gated in this state.
+ * + * This enables entry in LPSS if: + * - Sensor Subsystem is in SS2 + * - Lakemont is in C2 or C2LP + * - LPSS entry is enabled + * + * A wake event causes the Sensor Subsystem to transition to SS0.
+ * There are two kinds of wake event depending on the Sensor Subsystem + * and SoC state: + * - SS2: a wake event is a Sensor Subsystem interrupt + * - LPSS: a wake event is a Sensor Subsystem interrupt or a Lakemont interrupt + * + * LPSS wake events apply if LPSS is entered. + * If Host wakes the SoC from LPSS, + * Sensor also transitions back to SS0. + */ +//void ss_power_cpu_ss2(void); + +/** + * Save resume vector. + * + * Saves the resume vector in the global "arc_restore_addr" location. + * The ARC will jump to the resume vector once a wake up event is + * triggered and x86 resumes the ARC. + */ +#define qm_ss_set_resume_vector(_restore_label, arc_restore_addr) \ + __asm__ __volatile__("mov r0, @arc_restore_addr\n\t" \ + "st " #_restore_label ", [r0]\n\t" \ + : /* Output operands. */ \ + : /* Input operands. */ \ + : /* Clobbered registers list. */ \ + "r0") + +/* Save execution context. + * + * This routine saves CPU registers onto cpu_context, + * array. + * + */ +#define qm_ss_save_context(cpu_context) \ + __asm__ __volatile__("push_s r0\n\t" \ + "mov r0, @cpu_context\n\t" \ + "st r1, [r0, 4]\n\t" \ + "st r2, [r0, 8]\n\t" \ + "st r3, [r0, 12]\n\t" \ + "st r4, [r0, 16]\n\t" \ + "st r5, [r0, 20]\n\t" \ + "st r6, [r0, 24]\n\t" \ + "st r7, [r0, 28]\n\t" \ + "st r8, [r0, 32]\n\t" \ + "st r9, [r0, 36]\n\t" \ + "st r10, [r0, 40]\n\t" \ + "st r11, [r0, 44]\n\t" \ + "st r12, [r0, 48]\n\t" \ + "st r13, [r0, 52]\n\t" \ + "st r14, [r0, 56]\n\t" \ + "st r15, [r0, 60]\n\t" \ + "st r16, [r0, 64]\n\t" \ + "st r17, [r0, 68]\n\t" \ + "st r18, [r0, 72]\n\t" \ + "st r19, [r0, 76]\n\t" \ + "st r20, [r0, 80]\n\t" \ + "st r21, [r0, 84]\n\t" \ + "st r22, [r0, 88]\n\t" \ + "st r23, [r0, 92]\n\t" \ + "st r24, [r0, 96]\n\t" \ + "st r25, [r0, 100]\n\t" \ + "st r26, [r0, 104]\n\t" \ + "st r27, [r0, 108]\n\t" \ + "st r28, [r0, 112]\n\t" \ + "st r29, [r0, 116]\n\t" \ + "st r30, [r0, 120]\n\t" \ + "st r31, [r0, 124]\n\t" \ + "lr r31, [ic_ctrl]\n\t" \ + "st r31, [r0, 128]\n\t" \ + : /* Output operands. */ \ + : /* Input operands. */ \ + [ic_ctrl] "i"(QM_SS_AUX_IC_CTRL) \ + : /* Clobbered registers list. */ \ + "r0") + +/* Restore execution context. + * + * This routine restores CPU registers from cpu_context, + * array. + * + * This routine is called from the bootloader to restore the execution context + * from before entering in sleep mode. + */ +#define qm_ss_restore_context(_restore_label, cpu_context) \ + __asm__ __volatile__( \ + #_restore_label \ + ":\n\t" \ + "mov r0, @cpu_context\n\t" \ + "ld r1, [r0, 4]\n\t" \ + "ld r2, [r0, 8]\n\t" \ + "ld r3, [r0, 12]\n\t" \ + "ld r4, [r0, 16]\n\t" \ + "ld r5, [r0, 20]\n\t" \ + "ld r6, [r0, 24]\n\t" \ + "ld r7, [r0, 28]\n\t" \ + "ld r8, [r0, 32]\n\t" \ + "ld r9, [r0, 36]\n\t" \ + "ld r10, [r0, 40]\n\t" \ + "ld r11, [r0, 44]\n\t" \ + "ld r12, [r0, 48]\n\t" \ + "ld r13, [r0, 52]\n\t" \ + "ld r14, [r0, 56]\n\t" \ + "ld r15, [r0, 60]\n\t" \ + "ld r16, [r0, 64]\n\t" \ + "ld r17, [r0, 68]\n\t" \ + "ld r18, [r0, 72]\n\t" \ + "ld r19, [r0, 76]\n\t" \ + "ld r20, [r0, 80]\n\t" \ + "ld r21, [r0, 84]\n\t" \ + "ld r22, [r0, 88]\n\t" \ + "ld r23, [r0, 92]\n\t" \ + "ld r24, [r0, 96]\n\t" \ + "ld r25, [r0, 100]\n\t" \ + "ld r26, [r0, 104]\n\t" \ + "ld r27, [r0, 108]\n\t" \ + "ld r28, [r0, 112]\n\t" \ + "ld r29, [r0, 116]\n\t" \ + "ld r30, [r0, 120]\n\t" \ + "ld r31, [r0, 124]\n\t" \ + "ld r0, [r0, 128]\n\t" \ + "sr r0, [ic_ctrl]\n\t" \ + "pop_s r0\n\t" \ + "sr 0,[0x101]\n\t" /* Setup Sensor Subsystem TimeStamp Counter */ \ + "sr 0,[0x100]\n\t" \ + "sr -1,[0x102]\n\t" \ + : /* Output operands. */ \ + : /* Input operands. */ \ + [ic_ctrl] "i"(QM_SS_AUX_IC_CTRL) \ + : /* Clobbered registers list. */ \ + "r0") + +/** + * @} + */ + +#endif /* __QM_SS_POWER_STATES_H__ */ diff --git a/libraries/CuriePowerManagement/src/wsrc.c b/libraries/CuriePowerManagement/src/wsrc.c new file mode 100644 index 00000000..abc8c1f2 --- /dev/null +++ b/libraries/CuriePowerManagement/src/wsrc.c @@ -0,0 +1,172 @@ +#include +#include "dccm/dccm_alloc.h" +#include "wsrc.h" +#include "string.h" + +#ifdef __cplusplus + extern "C" { +#endif + +static uint8_t new_index = 0; +static uint8_t old_index = 0; +static uint8_t num_active = 0; +static wsrc_active_t wsrc_active[MAX_ATTACHABLE]; + +wsrc_entry_t wsrc_table[NUM_WAKEUP] = { + { .irq = IRQ_GPIO1_INTR, .status = 0 }, /* I00 */ + { .irq = IRQ_GPIO1_INTR, .status = 0 }, /* I01 */ + { .irq = IRQ_GPIO_INTR, .status = 0 }, /* I02 */ + { .irq = IRQ_GPIO1_INTR, .status = 0 }, /* I03 */ + { .irq = IRQ_GPIO_INTR, .status = 0 }, /* I04 */ + { .irq = IRQ_GPIO1_INTR, .status = 0 }, /* I05 */ + { .irq = IRQ_GPIO1_INTR, .status = 0 }, /* I06 */ + { .irq = IRQ_GPIO_INTR, .status = 0 }, /* I07 */ + { .irq = IRQ_GPIO_INTR, .status = 0 }, /* I08 */ + { .irq = IRQ_GPIO1_INTR, .status = 0 }, /* I09 */ + { .irq = IRQ_GPIO_INTR, .status = 0 }, /* I010 */ + { .irq = IRQ_GPIO_INTR, .status = 0 }, /* I011 */ + { .irq = IRQ_GPIO_INTR, .status = 0 }, /* I012 */ + { .irq = IRQ_GPIO_INTR, .status = 0 }, /* I013 */ + { .irq = IRQ_GPIO0_INTR, .status = 0 }, /* I014 */ + { .irq = IRQ_GPIO0_INTR, .status = 0 }, /* I015 */ + { .irq = IRQ_GPIO0_INTR, .status = 0 }, /* I016 */ + { .irq = IRQ_GPIO0_INTR, .status = 0 }, /* I017 */ + { .irq = IRQ_GPIO0_INTR, .status = 0 }, /* I018 */ + { .irq = IRQ_GPIO0_INTR, .status = 0 }, /* I019 */ + { .irq = IRQ_GPIO0_INTR, .status = 0 }, /* I020 */ + { .irq = IRQ_GPIO_INTR, .status = 0 }, /* I021 */ + { .irq = IRQ_GPIO_INTR, .status = 0 }, /* I022 */ + { .irq = IRQ_GPIO_INTR, .status = 0 }, /* I023 */ + { .irq = IRQ_GPIO_INTR, .status = 0 }, /* I024 */ + { .irq = IRQ_GPIO_INTR, .status = 0 }, /* I025 */ + { .irq = IRQ_ALWAYS_ON_GPIO, .status = 1 }, /* IO26 AON_GPIO0*/ + { .irq = IRQ_ALWAYS_ON_GPIO, .status = 1 }, /* IO27 AON_GPIO1*/ + { .irq = IRQ_ALWAYS_ON_GPIO, .status = 1 }, /* IO28 AON_GPIO2*/ + { .irq = IRQ_ALWAYS_ON_GPIO, .status = 1 }, /* IO29 AON_GPIO3*/ + { .irq = IRQ_ALWAYS_ON_GPIO, .status = 1 }, /* BLE_WAKEUP */ + { .irq = IRQ_ALWAYS_ON_GPIO, .status = 1 }, /* IMU_WAKEUP */ + { .irq = IRQ_I2S_INTR, .status = 0 }, /* I2S_WAKEUP */ + { .irq = IRQ_I2C0_RX_AVAIL, .status = 0 }, /* WIRE_RX_WAKEUP */ + { .irq = IRQ_USB_INTR, .status = 0 }, /* SERIAL_WAKEUP */ + { .irq = IRQ_UART1_INTR, .status = 0 }, /* SERIAL1_WAKEUP */ + { .irq = IRQ_ADC_IRQ, .status = 0 }, /* ADC_WAKEUP */ + { .irq = IRQ_ALWAYS_ON_TMR, .status = 0 }, /* AON_TIMER_WAKEUP */ + { .irq = IRQ_TIMER1, .status = 0 }, /* TIMER1_WAKEUP */ + { .irq = IRQ_PWM_TIMER_INTR, .status = 0 }, /* PWM_TIMER_WAKEUP */ + { .irq = IRQ_SPI1_RX_AVAIL, .status = 0 }, /* SPI_RX_WAKEUP */ + { .irq = IRQ_SPI0_RX_AVAIL, .status = 0 }, /* SPI1_RX_WAKEUP */ + { .irq = IRQ_RTC_INTR, .status = 1 }, /* RTC_WAKEUP */ + { .irq = IRQ_WDOG_INTR, .status = 0 }, /* WATCHDOG_WAKEUP */ + { .irq = IRQ_MAILBOXES_INTR, .status = 0 }, /* MAILBOX_WAKEUP */ + { .irq = IRQ_COMPARATORS_INTR, .status = 1},/* COMPARATORS_WAKEUP*/ +}; + +static void wsrc_set_active (uint8_t index, void (*cb)(void)) +{ + if (num_active < MAX_ATTACHABLE) { + wsrc_active[num_active].cb = (uint32_t)cb; + wsrc_active[num_active++].index = index; + ++new_index; + } +} + +static void wsrc_clear_active (uint8_t index) +{ + unsigned int i, j; + + for (i = 0; i < num_active; i++) { + + /* Look for this value in wsrc_active ... */ + if (wsrc_active[i].index == index) { + + /* ... and shift over all remaining values that follow it */ + for (j = i + 1; j < num_active; j++) { + wsrc_active[j - 1] = wsrc_active[j]; + } + --num_active; + --new_index; + break; + } + } +} + +int wsrc_getIndex(int id) +{ + for (int i = 0; i < num_active; i++) { + if (wsrc_active[i].index == id){ + return i; + } + } + return 0; +} + +int wsrc_get_newest_attached (wsrc_t *wsrc) +{ + uint8_t i; + + if(num_active == 0){ + return 0; + } + + if (new_index == 0 || !wsrc) { + new_index = num_active; + return 0; + } + + i = wsrc_active[--new_index].index; + + wsrc->irq = wsrc_table[i].irq; + wsrc->callback = wsrc_active[new_index].cb; + wsrc->status = wsrc_table[i].status; + wsrc->id = i; + + return 1; +} + +int wsrc_get_oldest_attached (wsrc_t *wsrc) +{ + uint8_t i; + + if (old_index == num_active || !wsrc) { + old_index = 0; + return 0; + } + + i = wsrc_active[old_index].index; + + wsrc->irq = wsrc_table[i].irq; + wsrc->callback = wsrc_active[old_index++].cb; + wsrc->status = wsrc_table[i].status; + wsrc->id = i; + + return 1; +} + +void wsrc_register_gpio (uint32_t pin, void (*callback)(void), uint32_t mode) +{ + /* Set interrupt mode */ + wsrc_set_gpio_mode(SRC_STAT(pin), mode); + + if (!wsrc_wakeup(SRC_STAT(pin))) { + wsrc_set_active(pin, callback); + wsrc_set_wakeup(SRC_STAT(pin)); + } +} + +void wsrc_register_id (int id, void (*callback)(void)) +{ + if (!wsrc_wakeup(SRC_STAT(id))) { + wsrc_set_active(id, callback); + wsrc_set_wakeup(SRC_STAT(id)); + } +} + +void wsrc_unregister (int id) +{ + wsrc_clear_active(id); + wsrc_clear_wakeup(SRC_STAT(id)); +} + +#ifdef __cplusplus +} +#endif diff --git a/libraries/CuriePowerManagement/src/wsrc.h b/libraries/CuriePowerManagement/src/wsrc.h new file mode 100644 index 00000000..d4e0fcb5 --- /dev/null +++ b/libraries/CuriePowerManagement/src/wsrc.h @@ -0,0 +1,113 @@ +#ifndef WSRC_H_ +#define WSRC_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "board.h" +#include "pins_arduino.h" + +#define GPIO_START 0 +#define GPIO_END (NUM_DIGITAL_PINS - 6) + +#define GPIO_MODE_MASK 0x38 +#define SRC_STAT(src) (wsrc_table[src].status) + +#define MAX_ATTACHABLE 10 +#define wsrc_cansleep(stat) (stat & 1) +#define wsrc_working(stat) (stat & 2) +#define wsrc_wakeup(stat) (stat & 4) +#define wsrc_set_cansleep(stat) (stat |= 1) +#define wsrc_clear_cansleep(stat) (stat &= ~1) +#define wsrc_set_working(stat) (stat |= 2) +#define wsrc_clear_working(stat) (stat &= ~2) +#define wsrc_set_wakeup(stat) (stat |= 4) +#define wsrc_clear_wakeup(stat) (stat &= ~4) +#define wsrc_gpio_mode(stat) ((stat & GPIO_MODE_MASK) >> 3) +#define wsrc_set_gpio_mode(stat, mode)({\ + stat &= ~GPIO_MODE_MASK;\ + stat |= (mode << 3);\ + }); + +enum { + /* TODO: not all of these can actually be used as wakeup sources. + * find out which ones they are. */ + AON_GPIO0 = GPIO_END , + AON_GPIO1 = GPIO_END + 1, + AON_GPIO2 = GPIO_END + 2, + AON_GPIO3 = GPIO_END + 3 , + IMU_WAKEUP = GPIO_END + 4, + BLE_WAKEUP = GPIO_END + 5, + I2S_WAKEUP = GPIO_END + 6, + WIRE_RX_WAKEUP = GPIO_END + 7, + SERIAL_WAKEUP = GPIO_END + 8, + SERIAL1_WAKEUP = GPIO_END + 9, + ADC_WAKEUP = GPIO_END + 10, + AON_TIMER_WAKEUP = GPIO_END + 11, + TIMER1_WAKEUP = GPIO_END + 12, + PWM_TIMER_WAKEUP = GPIO_END + 13, + SPI_RX_WAKEUP = GPIO_END + 14, + SPI1_RX_WAKEUP = GPIO_END + 15, + RTC_WAKEUP = GPIO_END + 16, + WATCHDOG_WAKEUP = GPIO_END + 17, + MAILBOX_WAKEUP = GPIO_END + 18, + COMPARATORS_WAKEUP = GPIO_END + 19, + NUM_WAKEUP = GPIO_END + 20 +}; + +struct wsrc_entry { + /* IRQ associated with this wakeup source */ + uint8_t irq; + /* Status flags; + * + * Bit 0: sleep: indicates if this wakeup source can be used in + * deeper sleep modes (if unset, can only be used in + * doze mode) + * Bit 1: working: indicates this entry is waiting for something + * to complete in interrupt context (e.g. + * interrupt-based UART transfer in progress) + * Bit 2: wakeup: indicates this entry is to be used as a wakeup + * source + * Bits 3-5: GPIO mode: 0 - LOW + * 1 - HIGH + * 2 - CHANGE + * 3 - FALLING + * 4 - RISING + * + * Bits 6-7: Reserved. */ + volatile uint8_t status; +} __attribute__((packed)); + +struct wsrc_active { + uint32_t cb; + uint8_t index; +} __attribute__((packed)); + +struct wsrc { + uint32_t callback; + uint8_t status; + uint8_t irq; + uint8_t id; +}; + +typedef struct wsrc wsrc_t; +typedef struct wsrc_entry wsrc_entry_t; +typedef struct wsrc_active wsrc_active_t; + +extern wsrc_entry_t wsrc_table[NUM_WAKEUP]; + +void wsrc_table_init (void); +void wsrc_register_gpio (uint32_t pin, void (*callback)(void), uint32_t mode); +void wsrc_register_id (int id, void (*callback)(void)); +void wsrc_unregister (int id); +int wsrc_getIndex(int id); + +int wsrc_get_newest_attached (wsrc_t *wsrc); +int wsrc_get_oldest_attached (wsrc_t *wsrc); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libraries/CurieSoftwareSerial/src/SoftwareSerial.cpp b/libraries/CurieSoftwareSerial/src/SoftwareSerial.cpp index 8be77370..4d3a6365 100644 --- a/libraries/CurieSoftwareSerial/src/SoftwareSerial.cpp +++ b/libraries/CurieSoftwareSerial/src/SoftwareSerial.cpp @@ -226,9 +226,7 @@ SoftwareSerial::SoftwareSerial(uint32_t receivePin, uint32_t transmitPin, bool i _inverse_logic(inverse_logic) { _inverse_logic = inverse_logic; - setTX(transmitPin); _transmitPin = transmitPin; - setRX(receivePin); _receivePin = receivePin; _receive_buffer = (char*)dccm_malloc(_SS_MAX_RX_BUFF); } @@ -272,6 +270,9 @@ uint16_t SoftwareSerial::subtract_cap(uint16_t num, uint16_t sub) { void SoftwareSerial::begin(long speed) { + setTX(_transmitPin); + setRX(_receivePin); + _rx_delay_centering = _rx_delay_intrabit = _rx_delay_stopbit = _tx_delay = 0; //pre-calculate delays _bit_delay = (F_CPU/speed); diff --git a/libraries/CurieTimerOne/keywords.txt b/libraries/CurieTimerOne/keywords.txt index 734a16df..87562f6a 100644 --- a/libraries/CurieTimerOne/keywords.txt +++ b/libraries/CurieTimerOne/keywords.txt @@ -6,29 +6,29 @@ # Datatypes (KEYWORD1) ####################################### -CurieTimer KEYWORD1 +CurieTimer KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) ####################################### -initialize KEYWORD2 -setPeriod KEYWORD2 -start KEYWORD2 -stop KEYWORD2 -restart KEYWORD2 -resume KEYWORD2 -setPwmDuty KEYWORD2 -pwm KEYWORD2 -disablePwm KEYWORD2 -attachInterrupt KEYWORD2 -detachInterrupt KEYWORD2 -kill KEYWORD2 -readTickCount KEYWORD2 -rdRstTickCount KEYWORD2 -pause KEYWORD2 -pwmStart KEYWORD2 -pwmStop KEYWORD2 +initialize KEYWORD2 +setPeriod KEYWORD2 +start KEYWORD2 +stop KEYWORD2 +restart KEYWORD2 +resume KEYWORD2 +setPwmDuty KEYWORD2 +pwm KEYWORD2 +disablePwm KEYWORD2 +attachInterrupt KEYWORD2 +detachInterrupt KEYWORD2 +kill KEYWORD2 +readTickCount KEYWORD2 +rdRstTickCount KEYWORD2 +pause KEYWORD2 +pwmStart KEYWORD2 +pwmStop KEYWORD2 ####################################### # Instances (KEYWORD2) ####################################### -CurieTimerOne KEYWORD2 +CurieTimerOne KEYWORD2 diff --git a/libraries/EEPROM/src/EEPROM.cpp b/libraries/EEPROM/src/EEPROM.cpp index 327061fc..de567eed 100644 --- a/libraries/EEPROM/src/EEPROM.cpp +++ b/libraries/EEPROM/src/EEPROM.cpp @@ -54,7 +54,7 @@ void CurieRestoreMemory(uint32_t* buffer, uint32_t size) rom_wr_ctrl |= 0x00000001; //set (WR_REQ) bit *(uint32_t*)(ROM_WR_CTRL) = rom_wr_ctrl; - delay(3); //give it enough time to finish writing + delay(5); //give it enough time to finish writing } } @@ -121,5 +121,5 @@ void CurieWrite8(uint32_t address, uint8_t data) rom_wr_ctrl |= 0x00000001; //set (WR_REQ) bit *(uint32_t*)(ROM_WR_CTRL) = rom_wr_ctrl; - delay(3); //give it enough time to finish writing + delay(5); //give it enough time to finish writing } diff --git a/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino b/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino index b135a74f..a06f1133 100644 --- a/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino +++ b/libraries/SPI/examples/DigitalPotControl/DigitalPotControl.ino @@ -63,9 +63,11 @@ void loop() { void digitalPotWrite(int address, int value) { // take the SS pin low to select the chip: digitalWrite(slaveSelectPin, LOW); + delay(100); // send in the address and value via SPI: SPI.transfer(address); SPI.transfer(value); + delay(100); // take the SS pin high to de-select the chip: digitalWrite(slaveSelectPin, HIGH); } diff --git a/libraries/SPI/keywords.txt b/libraries/SPI/keywords.txt index ff058279..05834754 100644 --- a/libraries/SPI/keywords.txt +++ b/libraries/SPI/keywords.txt @@ -7,7 +7,7 @@ ####################################### SPI KEYWORD1 -SPI1 KEYWORD1 +SPI1 KEYWORD1 ####################################### # Methods and Functions (KEYWORD2) diff --git a/libraries/Wire/examples/bus_scan/bus_scan.ino b/libraries/Wire/examples/bus_scan/bus_scan.ino index 65fc0946..22ef7495 100644 --- a/libraries/Wire/examples/bus_scan/bus_scan.ino +++ b/libraries/Wire/examples/bus_scan/bus_scan.ino @@ -47,7 +47,7 @@ void setup() while(!Serial); } -boolean toggle = false; // state of the LED +bool toggle = false; // state of the LED void loop() { toggle = !toggle; diff --git a/platform.txt b/platform.txt index e60f5ceb..66812628 100644 --- a/platform.txt +++ b/platform.txt @@ -5,7 +5,7 @@ # https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5---3rd-party-Hardware-specification name=Intel Curie (32-bit) Boards -version=2.0.0 +version=2.1.0 # Arduino 101 compile variables # ---------------------- @@ -71,8 +71,7 @@ recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} {compil recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} "-T{build.variant.path}/{build.ldscript}" "-Wl,-Map,{build.path}/{build.project_name}.map" {compiler.c.elf.extra_flags} -o "{build.path}/{build.project_name}.elf" "-L{build.path}" "-L{build.variant.path}" -Wl,--whole-archive "-l{build.variant_system_lib}" -Wl,--no-whole-archive -Wl,--start-group "-l{build.variant_system_lib}" -lnsim -lc -lm -lgcc {object_files} "{build.path}/{archive_file}" ## Save output with debug symbols (.debug.elf file). Uncomment if you wish to use OpenOCD to debug. -recipe.hooks.objcopy.preobjcopy.1.pattern=cp -f "{build.path}/{build.project_name}.elf" "{build.path}/../arduino101_sketch.debug.elf" -recipe.hooks.objcopy.preobjcopy.1.pattern.windows={runtime.tools.arduino101load.path}/arduino101load/arduino101copy.exe "{build.path}\{build.project_name}.elf" "{build.path}\..\arduino101_sketch.debug.elf" +recipe.hooks.objcopy.preobjcopy.1.pattern="{runtime.tools.arduino101load.path}/arduino101load" -c -from="{build.path}/{build.project_name}.elf" -to="{build.path}/../arduino101_sketch.debug.elf" ## Create output (.bin file) recipe.objcopy.bin.pattern="{compiler.path}{compiler.elf2bin.cmd}" {compiler.elf2bin.flags} {compiler.elf2hex.extra_flags} "{build.path}/{build.project_name}.elf" "{build.path}/{build.project_name}.bin" @@ -91,25 +90,29 @@ recipe.output.save_file={build.project_name}.{build.variant}.hex recipe.size.pattern="{compiler.path}{compiler.size.cmd}" -A "{build.path}/{build.project_name}.elf" recipe.size.regex=^(?:text|ctors|rodata|datas)\s+([0-9]+).* -# BLE firmware check +# Firmware check # ------------------- tools.arduino101load.ble.fw.string="ATP1BLE00R-1631C4439" tools.arduino101load.ble.fw.position=169984 +# Dummy RTOS walues - don't update RTOS if not strictly needed +tools.arduino101load.rtos.fw.string="firmware_1.8.0_arduino101" +tools.arduino101load.rtos.fw.position=147424 +#not ideal - should be inherited by the platform +tools.arduino101load.version=2.2.0 # Arc Uploader/Programmers tools # ------------------- -tools.arduino101load.cmd.path={runtime.tools.arduino101load.path}/arduino101load/arduino101load +tools.arduino101load.cmd.path={runtime.tools.arduino101load.path}/arduino101load -tools.arduino101load.upload.params.verbose=verbose -tools.arduino101load.upload.params.quiet=quiet +tools.arduino101load.upload.params.verbose=-v +tools.arduino101load.upload.params.quiet=-q -tools.arduino101load.upload.pattern="{cmd.path}" "{runtime.tools.arduino101load.path}/x86/bin" "{build.path}/{build.project_name}.bin" {serial.port} "{upload.verbose}" {ble.fw.string} {ble.fw.position} +tools.arduino101load.upload.pattern="{cmd.path}" "-dfu={runtime.tools.dfu-util.path}" "-bin={build.path}/{build.project_name}.bin" -port={serial.port} "{upload.verbose}" -ble_fw_str={ble.fw.string} -ble_fw_pos={ble.fw.position} -rtos_fw_str={rtos.fw.string} -rtos_fw_pos={rtos.fw.position} -core={version} # This is needed to avoid an error on unexistent fields tools.arduino101load.erase.params.verbose= tools.arduino101load.erase.params.quiet= tools.arduino101load.erase.pattern= -tools.arduino101load.bootloader.params.verbose= -tools.arduino101load.bootloader.params.quiet= -tools.arduino101load.bootloader.pattern={runtime.tools.flashpack.path}/flash_dfu.sh -tools.arduino101load.bootloader.pattern.windows={runtime.tools.flashpack.path}/flash_dfu.bat +tools.arduino101load.bootloader.params.verbose=-v +tools.arduino101load.bootloader.params.quiet=-q +tools.arduino101load.bootloader.pattern="{cmd.path}" "-dfu={runtime.tools.dfu-util.path}" -port={serial.port} "{bootloader.verbose}" -f -core={version} diff --git a/post_install.bat b/post_install.bat new file mode 100644 index 00000000..73e16e14 --- /dev/null +++ b/post_install.bat @@ -0,0 +1,10 @@ +@echo off +set ARGS=/A /SE /SW /SA +if "%PROCESSOR_ARCHITECTURE%" == "AMD64" ( + drivers\dpinst-amd64.exe %ARGS% +) ELSE IF "%PROCESSOR_ARCHITEW6432%" == "AMD64" ( + drivers\dpinst-amd64.exe %ARGS% +) ELSE ( + drivers\dpinst-x86.exe %ARGS% +) +exit /b 0 diff --git a/scripts/create_dfu_udev_rule b/scripts/create_dfu_udev_rule new file mode 100755 index 00000000..4e64ea64 --- /dev/null +++ b/scripts/create_dfu_udev_rule @@ -0,0 +1,17 @@ +#!/bin/bash +# + +if [ "$(id -u)" != "0" ]; then + echo "This script must be run as root" + exit +fi + +NAME=99-arduino-101.rules + +echo >/etc/udev/rules.d/$NAME +echo \# Arduino 101 in DFU Mode >>/etc/udev/rules.d/$NAME +echo SUBSYSTEM==\"tty\", ENV{ID_REVISION}==\"8087\", ENV{ID_MODEL_ID}==\"0ab6\", MODE=\"0666\", ENV{ID_MM_DEVICE_IGNORE}=\"1\", ENV{ID_MM_CANDIDATE}=\"0\" >>/etc/udev/rules.d/$NAME +echo SUBSYSTEM==\"usb\", ATTR{idVendor}==\"8087\", ATTR{idProduct}==\"0aba\", MODE=\"0666\", ENV{ID_MM_DEVICE_IGNORE}=\"1\" >>/etc/udev/rules.d/$NAME + +udevadm control --reload-rules +udevadm trigger diff --git a/variants/arduino_101/linker_scripts/flash.ld b/variants/arduino_101/linker_scripts/flash.ld index 335f7ef6..7ba34942 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 = 0xa800a000, LENGTH = 40K DCCM (wx) : ORIGIN = 0x80000000, LENGTH = 8K } @@ -52,7 +52,7 @@ __firq_stack_size = 1024; /* Minimum heap size to allocate * Actual heap size might be bigger due to page size alignment */ -__HEAP_SIZE_MIN = 8192; +__HEAP_SIZE_MIN = 16384; /* This should be set to the page size used by the malloc implementation */ __PAGE_SIZE = 4096; diff --git a/variants/arduino_101/variant.cpp b/variants/arduino_101/variant.cpp index 31473536..ebcf884c 100644 --- a/variants/arduino_101/variant.cpp +++ b/variants/arduino_101/variant.cpp @@ -21,6 +21,7 @@ #include "cfw_platform.h" #include "platform.h" +#include "mailbox.h" // Add for debug corelib #ifdef CONFIGURE_DEBUG_CORELIB_ENABLED @@ -254,6 +255,9 @@ void initVariant( void ) *SYS_CLK_CTL |= 1 << CCU_RTC_CLK_DIV_EN; cfw_platform_init(); + + /* Ready the mailbox for use (but don't initialise HW; x86 does that) */ + mailbox_init(false); // Add for debug corelib #ifdef CONFIGURE_DEBUG_CORELIB_ENABLED