by Crossware
27. August 2014 10:07
Continuing with my theme of yesterday where I wrote to the U40 MSP23017 soft switch chip to enable SW4 and SW5, I will show you how to read the register values from this U40 chip.
I've created two subroutines - WriteRegisterValue() and ReadRegisterValue() to make the main function clearer.
You will see below that I am writing to register 0X15 which is the output latch OLATB register whereas yesterday I wrote to register 0X13 GPIOB. But if you read back the value of register 0X13 after you have written to it, you do not see the value that you have written. Instead you have to read OLATB to see this value. The MSP23017 data sheet explains that a write to GPIOB is actually a write to OLATB and a read of GPIOB reads the port pins. So to avoid confusion, I write directly to OLATB instead.
#include "xstdsys.h"
unsigned char regValues[0X16];
void WriteRegisterValue(unsigned char address, unsigned char value)
{
g_pTWI0->MSTRCTL &= ~(TWI_MSTRCTL_DCNT0 | TWI_MSTRCTL_DCNT1 | TWI_MSTRCTL_DCNT2 | TWI_MSTRCTL_DCNT3 | TWI_MSTRCTL_DCNT4 | TWI_MSTRCTL_DCNT5 | TWI_MSTRCTL_DCNT6 | TWI_MSTRCTL_DCNT7);
g_pTWI0->MSTRCTL |= 0X02 << 6; // transmit 2 bytes
g_pTWI0->MSTRCTL &= ~TWI_MSTRCTL_DIR; // transmit
g_pTWI0->TXDATA8 = address;
g_pTWI0->MSTRCTL |= TWI_MSTRCTL_EN;
while (g_pTWI0->FIFOSTAT & (TWI_FIFOSTAT_TXSTAT0 | TWI_FIFOSTAT_TXSTAT1));
while ((g_pTWI0->ISTAT & TWI_ISTAT_TXSERV) == 0);
g_pTWI0->ISTAT = TWI_ISTAT_TXSERV;
g_pTWI0->TXDATA8 = value;
while ((g_pTWI0->ISTAT & TWI_ISTAT_MCOMP) == 0);
g_pTWI0->ISTAT = TWI_ISTAT_TXSERV | TWI_ISTAT_MCOMP;
}
unsigned char ReadRegisterValue(unsigned char address)
{
// send register address
g_pTWI0->MSTRCTL &= ~(TWI_MSTRCTL_DCNT0 | TWI_MSTRCTL_DCNT1 | TWI_MSTRCTL_DCNT2 | TWI_MSTRCTL_DCNT3 | TWI_MSTRCTL_DCNT4 | TWI_MSTRCTL_DCNT5 | TWI_MSTRCTL_DCNT6 | TWI_MSTRCTL_DCNT7);
g_pTWI0->MSTRCTL |= 0X01 << 6; // 1 byte
g_pTWI0->MSTRCTL &= ~TWI_MSTRCTL_DIR; // transmit
g_pTWI0->TXDATA8 = address;
g_pTWI0->MSTRCTL |= TWI_MSTRCTL_EN;
while (g_pTWI0->FIFOSTAT & (TWI_FIFOSTAT_TXSTAT0 | TWI_FIFOSTAT_TXSTAT1));
while ((g_pTWI0->ISTAT & TWI_ISTAT_TXSERV) == 0);
while ((g_pTWI0->ISTAT & TWI_ISTAT_MCOMP) == 0);
g_pTWI0->ISTAT = TWI_ISTAT_TXSERV | TWI_ISTAT_MCOMP;
// read value
g_pTWI0->MSTRCTL &= ~(TWI_MSTRCTL_DCNT0 | TWI_MSTRCTL_DCNT1 | TWI_MSTRCTL_DCNT2 | TWI_MSTRCTL_DCNT3 | TWI_MSTRCTL_DCNT4 | TWI_MSTRCTL_DCNT5 | TWI_MSTRCTL_DCNT6 | TWI_MSTRCTL_DCNT7);
g_pTWI0->MSTRCTL |= 0X01 << 6; // 1 byte
g_pTWI0->MSTRCTL |= TWI_MSTRCTL_DIR; // receive
g_pTWI0->MSTRCTL |= TWI_MSTRCTL_EN;
while ((g_pTWI0->FIFOSTAT & TWI_FIFOSTAT_RXSTAT0) == 0);
while ((g_pTWI0->ISTAT & TWI_ISTAT_MCOMP) == 0);
g_pTWI0->ISTAT = TWI_ISTAT_RXSERV | TWI_ISTAT_MCOMP;
return (unsigned char)g_pTWI0->RXDATA8;
}
main()
{
g_pTWI0->CLKDIV = 0XFFFF;
g_pTWI0->MSTRADDR = 0X0020; // U40
g_pTWI0->CTL = TWI_CTL_EN;
WriteRegisterValue(0X15, 0X3E); // write OLATB (output latch B)
for (unsigned char address = 0; address <= 0X15; address++)
{
regValues[address] = ReadRegisterValue(address);
}
while (1)
{
}
}
by Crossware
26. August 2014 18:32
We like examples to be as simple as possible and this is as simple as we can make it for controlling both the switches and the LEDs on the ADSP-CM408F EZ-KIT Lite Board.
The switches SW4 and SW5 are disabled by default and so from a 'No Boot - idle' mode, the soft switches must be configured. This means sending commands to the U40 chip using the TWI interface.
The TWI clock and data pins are not multiplexed and so there is no need to configure the GPIO in order to use them.
Possibly we could get away with fewer while loops in the code below and we could also run the TWI at a faster speed. But it works as written and that should get you started.
Pressing SW4 turns on LED1 and turns off LED2. Pressing SW5 turns on LED3 and turns off LED4.
#include "xstdsys.h"
#define DELAY 100000
#define LED1PIN 7
#define LED2PIN 6
#define LED3PIN 5
#define LED4PIN 9
#define SW4PIN 10
#define SW5PIN 8
main()
{
g_pTWI0->CLKDIV = 0XFFFF;
g_pTWI0->MSTRADDR = 0X0020; // U40
g_pTWI0->CTL = TWI_CTL_EN;
// set register 13 (gpiob) U40 to 0X3E
// register 1 (iodirb) defaults to 0XFF and so need not be configured
g_pTWI0->MSTRCTL &= ~(TWI_MSTRCTL_DCNT0 | TWI_MSTRCTL_DCNT1 | TWI_MSTRCTL_DCNT2 | TWI_MSTRCTL_DCNT3 | TWI_MSTRCTL_DCNT4 | TWI_MSTRCTL_DCNT5 | TWI_MSTRCTL_DCNT6 | TWI_MSTRCTL_DCNT7);
g_pTWI0->MSTRCTL |= 0X02 << 6; // transmit 2 bytes
g_pTWI0->TXDATA8 = 0X13; // GPIOB
g_pTWI0->MSTRCTL |= TWI_MSTRCTL_EN;
while (g_pTWI0->FIFOSTAT & (TWI_FIFOSTAT_TXSTAT0 | TWI_FIFOSTAT_TXSTAT1));
while ((g_pTWI0->ISTAT & TWI_ISTAT_TXSERV) == 0);
g_pTWI0->ISTAT = TWI_ISTAT_TXSERV;
g_pTWI0->TXDATA8 = 0X3E; // leds and switches enabled
while ((g_pTWI0->ISTAT & TWI_ISTAT_MCOMP) == 0);
g_pTWI0->ISTAT = TWI_ISTAT_TXSERV | TWI_ISTAT_MCOMP;
g_pPORTF->INEN_SET = 1 << SW4PIN; // enable input
g_pPORTE->INEN_SET = 1 << SW5PIN; // enable input
g_pPORTE->DIR_SET = 1 << LED1PIN; // set as output
g_pPORTE->DIR_SET = 1 << LED2PIN; // set as output
g_pPORTE->DIR_SET = 1 << LED3PIN; // set as output
g_pPORTE->DIR_SET = 1 << LED4PIN; // set as output
while (1)
{
if (g_pPORTF->DATA & (1 << SW4PIN))
{
g_pPORTE->DATA_SET = 1 << LED1PIN;
g_pPORTE->DATA_CLR = 1 << LED2PIN;
}
else
{
g_pPORTE->DATA_CLR = 1 << LED1PIN;
g_pPORTE->DATA_SET = 1 << LED2PIN;
}
if (g_pPORTE->DATA & (1 << SW5PIN))
{
g_pPORTE->DATA_SET = 1 << LED3PIN;
g_pPORTE->DATA_CLR = 1 << LED4PIN;
}
else
{
g_pPORTE->DATA_CLR = 1 << LED3PIN;
g_pPORTE->DATA_SET = 1 << LED4PIN;
}
}
}
by Crossware
26. August 2014 18:12
Here is the simplest example C program we can devise for toggling the LEDs on the ADSP-CM408F EX-KIT Lite Board.
All LEDs are on Port E. By default the LEDs are enabled and so the soft switched do not need to be configured. Only the GPIO directions need to be set to make them outputs.
#include "xstdsys.h"
#define DELAY 100000
#define LED1PIN 7
#define LED2PIN 6
#define LED3PIN 5
#define LED4PIN 9
main()
{
// the following four lines could be combined into one if desired
g_pPORTE->DIR_SET = 1 << LED1PIN; // set as output
g_pPORTE->DIR_SET = 1 << LED2PIN; // set as output
g_pPORTE->DIR_SET = 1 << LED3PIN; // set as output
g_pPORTE->DIR_SET = 1 << LED4PIN; // set as output
while (1)
{
for (volatile int i = 0; i < DELAY; i++);
g_pPORTE->DATA_SET = 1 << LED1PIN;
for (volatile int i = 0; i < DELAY; i++);
g_pPORTE->DATA_CLR = 1 << LED1PIN;
for (volatile int i = 0; i < DELAY; i++);
g_pPORTE->DATA_SET = 1 << LED2PIN;
for (volatile int i = 0; i < DELAY; i++);
g_pPORTE->DATA_CLR = 1 << LED2PIN;
for (volatile int i = 0; i < DELAY; i++);
g_pPORTE->DATA_SET = 1 << LED3PIN;
for (volatile int i = 0; i < DELAY; i++);
g_pPORTE->DATA_CLR = 1 << LED3PIN;
for (volatile int i = 0; i < DELAY; i++);
g_pPORTE->DATA_SET = 1 << LED4PIN;
for (volatile int i = 0; i < DELAY; i++);
g_pPORTE->DATA_CLR = 1 << LED4PIN;
}
}
by Crossware
15. August 2014 16:11
We are developing support for Analog Device's ADSP-CM40x microcontrollers.
We received our ADSP-CM408F EZ-KIT Lite board on Monday and set about investigating the operation of the JTAG/SWD debugger interface. Pretty soon we could download and run programs in SRAM. (Lots of omissions and errors in ADI's reference manual though so it took a lot longer to get there than it should have!)
As usual during such developments we incrementally work our way though the peripherals adding register definitions, simple context menu wizards, simulation and so on, testing that things work along the way.
There are lots of examples for this board provided by ADI but we couldn't find anything remotely simple. So here is how to read the input switches SW4 and SW5 and illiminate the LEDs LED1 and LED 2:
// Initial CPP Source File
#include "xstdsys.h"
main()
{
// use the Wizards (see Wizards menu) to configure the on-chip peripherals
g_pPORTF->INEN_SET = 1 << 10;
g_pPORTE->INEN_SET = 1 << 8;
g_pPORTE->DIR_SET = 1 << 7;
g_pPORTE->DIR_SET = 1 << 6;
while (1)
{
if (g_pPORTE->DATA & (1 << 8))
g_pPORTE->DATA_SET = 1 << 7;
else
g_pPORTE->DATA_CLR = 1 << 7;
if (g_pPORTF->DATA & (1 << 10))
g_pPORTE->DATA_SET = 1 << 6;
else
g_pPORTE->DATA_CLR = 1 << 6;
}
}
Pressing SW4 illuminates LED2 and pressing SW5 illuminates LED1. That's all there is to it if the board boots in the factory configuration (SPI master boot mode with POST installed).
However, the installed POST program has already configured the Soft Configuration switches. To use the switches and LEDs from 'No Boot - idle' mode, the Soft Configuration switches must be configured.