We do not expose a driver or API to read the boot switch settings on ADS products. Since the switches have meaning to the boot loader, and that behavior cannot be changed, they are of limited use for applications.
However, reading the switches is the best method to determine the mode in which the system was booted.
As an example, the switches on the Bitsy Plus are simply a couple of bits in a GPIO register of the SA1111. The code below shows how to read the register on the Bitsy Plus. Note that the logic of these switches is negative logic, so a switch in the OFF position turns the register bit ON.
#include "windows.h"
#define MEMORY_SIZE 0x10000
#define SA1111_ADDRESS 0x18000000
#define SA1111_GPIO_OFFSET 0x1000
#define SA1111_PB_DWR_OFFSET 0x14
extern "C" BOOL VirtualCopy(LPVOID lpvDestMem,
LPVOID lpvSrcMem,
DWORD dwSizeInBytes,
DWORD wProtectFlag);
BYTE ReadBootSwitches()
{
PVOID pMem = VirtualAlloc(0, MEMORY_SIZE, MEM_RESERVE, PAGE_NOACCESS);
if (!pMem)
{
RETAILMSG(1, (_T("Error %d at VirtualAlloc()\r\n"), GetLastError()));
return 0xFF;
}
if (!VirtualCopy (pMem, (PVOID)(SA1111_ADDRESS >> 8),
MEMORY_SIZE, PAGE_PHYSICAL|PAGE_READWRITE|PAGE_NOCACHE) == TRUE)
{
RETAILMSG(1, (_T("Error %d at VirtualCopy()\r\n"), GetLastError()));
return 0xFF;
}
DEBUGMSG(1, (_T("GPIO_CTRL_REGISTER: 0x%08x\r\n"), pMem));
DWORD *p = (DWORD *)pMem;
// offset to the GPIO base
p += (SA1111_GPIO_OFFSET / sizeof(DWORD));
DEBUGMSG(1, (_T("SA1111_GPIO_ADDRESS: 0x%08x\r\n"), p));
// offset to the PB_DWR register
p += (SA1111_PB_DWR_OFFSET / sizeof(DWORD));
DEBUGMSG(1, (_T("SA1111_PB_DWR: 0x%08x\r\n"), p));
DEBUGMSG(1, (_T("PB_DWR value: 0x%04x\r\n"), *p));
BYTE value = (BYTE)((*p & 0xC) >> 2);
VirtualFree(pMem, 0, MEM_RELEASE);
return value;
}
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
RETAILMSG(TRUE, (_T("Boot switch value: 0x%02x\r\n"), ReadBootSwitches()));
return 0;
}