Christian Dupaty 10/2021 IS31FL3731 with CHARLEPLEX LED MATRIX adaptation from Adafruit project to ARM MBEB, tested on NUCLEO L073RZ for original project on Arduino see https://learn.adafruit.com/animated-flame-pendant/overview

Dependencies:   mbed

Christian Dupaty 10/2021

IS31FL3731 with CHARLIEPLEX LED MATRIX adaptation from Adafruit project to ARM MBEB, tested on NUCLEO L073RZ

for original project on Arduino see https://learn.adafruit.com/animated-flame-pendant/overview

The program reads the data from an images file and places it alternately on pages 0 and 1 of IS31FL3731

Data structure in data.h :

first byte x1 PF and y1 pf, second byte x2 PF and y2 pf

loop from x1 to x2

loop from y1 to y2

copy from the third byte into the img buffer (144 bytes)

https://os.mbed.com/media/uploads/cdupaty/stm32_flame.jpg

data structure

const uint8_t anim[] = {
  0x00, 0x8F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x04, 0x0E, 0x19, 0x22, 0x22, 0x17, 0x09, 0x01, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x0D, 0x40, 0x99, 0xF2, 0xFF, 0xFF, 0xF4, 0x91, 0x38, 0x0B, 0x01,
  0x00, 0x00, 0x00, 0x16, 0x6B, 0xC6, 0xE5, 0xDB, 0xCF, 0xBC, 0x93, 0x4B,
  0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x48, 0xB4, 0xC8, 0xBC, 0xBA,
  0xB8, 0xAD, 0x8A, 0x42, 0x0E, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x0C, 0x40, 0x9D, 0xF4, 0xFF, 0xFF, 0xFF, 0xDB, 0x70, 0x24, 0x06, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x09, 0x19, 0x26, 0x2C, 0x29,
  0x1D, 0x0F, 0x05, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  0x00, 0x00, 0x00, 0x00, 0x00, 0x00

.............................
Committer:
cdupaty
Date:
Tue Oct 05 15:30:40 2021 +0000
Revision:
1:81948520c7ed
Parent:
0:eb53bdf2b7eb
more comments to understand the program

Who changed what in which revision?

UserRevisionLine numberNew contents of line
cdupaty 0:eb53bdf2b7eb 1 /*
cdupaty 0:eb53bdf2b7eb 2 Christian Dupaty 10/2021
cdupaty 0:eb53bdf2b7eb 3 IS31FL3731 with CHARLEPLEX LED MATRIX adaptation from Adafruit project to ARM MBEB, tested on NUCLEO L073RZ
cdupaty 0:eb53bdf2b7eb 4 for original project on Arduino see https://learn.adafruit.com/animated-flame-pendant/overview
cdupaty 0:eb53bdf2b7eb 5
cdupaty 0:eb53bdf2b7eb 6 The program reads the data from an image and places it alternately
cdupaty 0:eb53bdf2b7eb 7 on pages 0 and 1 of IS31FL3731
cdupaty 0:eb53bdf2b7eb 8
cdupaty 0:eb53bdf2b7eb 9 Data structure in data.h
cdupaty 0:eb53bdf2b7eb 10 first byte x1 PF and y1 pf
cdupaty 0:eb53bdf2b7eb 11 second byte x2 PF and y2 pf
cdupaty 0:eb53bdf2b7eb 12 loop from x1 to x2
cdupaty 0:eb53bdf2b7eb 13 loop from y1 to y2
cdupaty 0:eb53bdf2b7eb 14 copy from the third byte into the img buffer (144 bytes)
cdupaty 0:eb53bdf2b7eb 15
cdupaty 0:eb53bdf2b7eb 16 the I2C write method sends the write address then a series of data, the number of data is then specified
cdupaty 0:eb53bdf2b7eb 17 ex: Wire.write (I2C_ADDR, cmd, s); I2C_ADDR address on 8bits, cmd pointer to data to send, s number of data
cdupaty 0:eb53bdf2b7eb 18 */
cdupaty 0:eb53bdf2b7eb 19
cdupaty 1:81948520c7ed 20 //--------------------------------------------------------------------------
cdupaty 1:81948520c7ed 21 // Animated flame for Adafruit Pro Trinket. Uses the following parts:
cdupaty 1:81948520c7ed 22 // - Pro Trinket microcontroller (adafruit.com/product/2010 or 2000)
cdupaty 1:81948520c7ed 23 // (#2010 = 3V/12MHz for longest battery life, but 5V/16MHz works OK)
cdupaty 1:81948520c7ed 24 // - Charlieplex LED Matrix Driver (2946)
cdupaty 1:81948520c7ed 25 // - Charlieplex LED Matrix (2947, 2948, 2972, 2973 or 2974)
cdupaty 1:81948520c7ed 26 // - 350 mAh LiPoly battery (2750)
cdupaty 1:81948520c7ed 27 // - LiPoly backpack (2124)
cdupaty 1:81948520c7ed 28 // - SPDT Slide Switch (805)
cdupaty 1:81948520c7ed 29 //
cdupaty 1:81948520c7ed 30 // This is NOT good "learn from" code for the IS31FL3731; it is "squeeze
cdupaty 1:81948520c7ed 31 // every last byte from the Pro Trinket" code. If you're starting out,
cdupaty 1:81948520c7ed 32 // download the Adafruit_IS31FL3731 and Adafruit_GFX libraries, which
cdupaty 1:81948520c7ed 33 // provide functions for drawing pixels, lines, etc. This sketch also
cdupaty 1:81948520c7ed 34 // uses some ATmega-specific tricks and will not run as-is on other chips.
cdupaty 1:81948520c7ed 35 //--------------------------------------------------------------------------
cdupaty 1:81948520c7ed 36
cdupaty 1:81948520c7ed 37 #include "mbed.h"
cdupaty 0:eb53bdf2b7eb 38 #include "data.h" // Flame animation data
cdupaty 1:81948520c7ed 39 //#define debug // for some printf
cdupaty 0:eb53bdf2b7eb 40 #define I2C_ADDR 0xE8 // I2C address of Charlieplex matrix 0x74
cdupaty 0:eb53bdf2b7eb 41 I2C Wire(I2C_SDA, I2C_SCL);
cdupaty 0:eb53bdf2b7eb 42 uint8_t page = 0; // Front/back buffer control
cdupaty 0:eb53bdf2b7eb 43 const uint8_t *ptr = anim; // Current pointer into animation data
cdupaty 0:eb53bdf2b7eb 44 uint8_t img[9 * 16]; // Buffer for rendering image
cdupaty 0:eb53bdf2b7eb 45
cdupaty 0:eb53bdf2b7eb 46 //Buffer for I2C write method
cdupaty 0:eb53bdf2b7eb 47 char cmd[200];
cdupaty 0:eb53bdf2b7eb 48
cdupaty 0:eb53bdf2b7eb 49 // to select register on IS31FL3731, see datasheet page 9
cdupaty 0:eb53bdf2b7eb 50 void pageSelect(uint8_t n)
cdupaty 0:eb53bdf2b7eb 51 {
cdupaty 0:eb53bdf2b7eb 52 cmd[0]=0xFD;
cdupaty 0:eb53bdf2b7eb 53 cmd[1]=n;
cdupaty 0:eb53bdf2b7eb 54 Wire.write(I2C_ADDR,cmd,2); // attention write method close communications (stop condition is issued)
cdupaty 0:eb53bdf2b7eb 55 }
cdupaty 0:eb53bdf2b7eb 56
cdupaty 0:eb53bdf2b7eb 57 // SETUP FUNCTION - RUNS ONCE AT STARTUP -----------------------------------
cdupaty 0:eb53bdf2b7eb 58
cdupaty 0:eb53bdf2b7eb 59 void setup()
cdupaty 0:eb53bdf2b7eb 60 {
cdupaty 0:eb53bdf2b7eb 61 uint8_t i, p, s;
cdupaty 0:eb53bdf2b7eb 62
cdupaty 1:81948520c7ed 63 s=0; // s is a counter for I2C buffer (cmd) write method
cdupaty 0:eb53bdf2b7eb 64 pageSelect(0x0B); // Access to the Function Registers (page Night)
cdupaty 1:81948520c7ed 65 cmd[0]=0; // adress first internal register
cdupaty 1:81948520c7ed 66 s++;
cdupaty 0:eb53bdf2b7eb 67 for(i=0; i<=0x0C; i++)
cdupaty 0:eb53bdf2b7eb 68 {
cdupaty 0:eb53bdf2b7eb 69 cmd[i+1]=0x00;
cdupaty 0:eb53bdf2b7eb 70 if (i==0) cmd[i+1]=0x00; // 0x08 for Auto Frame Play Mode 0x00 for picture mode
cdupaty 0:eb53bdf2b7eb 71 if (i==0x0A) cmd[i+1]=0xFF; // all to 0 except shutdown register
cdupaty 0:eb53bdf2b7eb 72 s++;
cdupaty 0:eb53bdf2b7eb 73 }
cdupaty 0:eb53bdf2b7eb 74 Wire.write(I2C_ADDR,cmd,s);
cdupaty 0:eb53bdf2b7eb 75
cdupaty 0:eb53bdf2b7eb 76 for(p=0; p<2; p++)
cdupaty 0:eb53bdf2b7eb 77 {
cdupaty 0:eb53bdf2b7eb 78 s=0;
cdupaty 0:eb53bdf2b7eb 79 // For each page used (0 & 1)...
cdupaty 0:eb53bdf2b7eb 80 pageSelect(p); // Access the Frame Registers
cdupaty 0:eb53bdf2b7eb 81 cmd[0]=0; // Start from 1st LED control reg
cdupaty 0:eb53bdf2b7eb 82 s++;
cdupaty 0:eb53bdf2b7eb 83 for(i=0; i<0xB4; i++)
cdupaty 0:eb53bdf2b7eb 84 {
cdupaty 0:eb53bdf2b7eb 85 if (i<18) cmd[i+1]=0xFF; // Enable all LEDs (18*8=144)
cdupaty 0:eb53bdf2b7eb 86 else cmd[i+1]=0x00; // desable blink and PWM
cdupaty 0:eb53bdf2b7eb 87 s++;
cdupaty 0:eb53bdf2b7eb 88 }
cdupaty 0:eb53bdf2b7eb 89 Wire.write(I2C_ADDR,cmd,s);
cdupaty 0:eb53bdf2b7eb 90 }
cdupaty 0:eb53bdf2b7eb 91 }
cdupaty 0:eb53bdf2b7eb 92
cdupaty 0:eb53bdf2b7eb 93 void loop()
cdupaty 0:eb53bdf2b7eb 94 {
cdupaty 0:eb53bdf2b7eb 95 uint8_t a, x1, y1, x2, y2, x, y,s;
cdupaty 0:eb53bdf2b7eb 96 #ifdef debug
cdupaty 0:eb53bdf2b7eb 97 printf("-------------------------------------------------------------\n");
cdupaty 0:eb53bdf2b7eb 98 printf("start loop\n");
cdupaty 0:eb53bdf2b7eb 99 printf("-------------------------------------------------------------\n");
cdupaty 0:eb53bdf2b7eb 100 #endif
cdupaty 0:eb53bdf2b7eb 101 pageSelect(0x0B); // Function registers
cdupaty 0:eb53bdf2b7eb 102 cmd[0]=0x01; // Picture Display reg
cdupaty 0:eb53bdf2b7eb 103 cmd[1]=page;
cdupaty 0:eb53bdf2b7eb 104 Wire.write(I2C_ADDR,cmd,2);
cdupaty 0:eb53bdf2b7eb 105
cdupaty 0:eb53bdf2b7eb 106 page ^= 1; // Flip front/back buffer index
cdupaty 0:eb53bdf2b7eb 107
cdupaty 0:eb53bdf2b7eb 108 // Then render NEXT frame. Start by getting bounding rect for new frame:
cdupaty 0:eb53bdf2b7eb 109 a = *ptr++; // New frame X1/Y1
cdupaty 0:eb53bdf2b7eb 110 if(a >= 144) // 0x90
cdupaty 0:eb53bdf2b7eb 111 {
cdupaty 0:eb53bdf2b7eb 112 // EOD marker? (valid X1 never exceeds 8)
cdupaty 0:eb53bdf2b7eb 113 ptr = anim; // Reset animation data pointer to start
cdupaty 0:eb53bdf2b7eb 114 a = *ptr++; // and take first value
cdupaty 0:eb53bdf2b7eb 115 }
cdupaty 0:eb53bdf2b7eb 116 x1 = a >> 4; // X1 = high 4 bits
cdupaty 0:eb53bdf2b7eb 117 y1 = a & 0x0F; // Y1 = low 4 bits
cdupaty 0:eb53bdf2b7eb 118 a = *ptr++; // New frame X2/Y2
cdupaty 0:eb53bdf2b7eb 119 x2 = a >> 4; // X2 = high 4 bits
cdupaty 0:eb53bdf2b7eb 120 y2 = a & 0x0F; // Y2 = low 4 bits
cdupaty 0:eb53bdf2b7eb 121
cdupaty 0:eb53bdf2b7eb 122 // Read rectangle of data from anim[] into portion of img[] buffer
cdupaty 0:eb53bdf2b7eb 123 #ifdef debug
cdupaty 0:eb53bdf2b7eb 124 printf("x1= %d y1= %d x2= %d y2 = %d \n",x1,y1,x2,y2);
cdupaty 0:eb53bdf2b7eb 125 #endif
cdupaty 0:eb53bdf2b7eb 126 for(x=x1; x<=x2; x++) {
cdupaty 0:eb53bdf2b7eb 127 // Column-major
cdupaty 0:eb53bdf2b7eb 128 for(y=y1; y<=y2; y++)
cdupaty 0:eb53bdf2b7eb 129 {
cdupaty 0:eb53bdf2b7eb 130 img[(x << 4) + y] = *ptr++;
cdupaty 0:eb53bdf2b7eb 131 #ifdef debug
cdupaty 0:eb53bdf2b7eb 132 printf("x= %d y= %d data= %d \n",x,y,img[(x << 4) + y]);
cdupaty 0:eb53bdf2b7eb 133 #endif
cdupaty 0:eb53bdf2b7eb 134 }
cdupaty 0:eb53bdf2b7eb 135 }
cdupaty 0:eb53bdf2b7eb 136
cdupaty 0:eb53bdf2b7eb 137 // Write img[] to matrix (not actually displayed until next pass)
cdupaty 0:eb53bdf2b7eb 138 pageSelect(page); // Select background buffer
cdupaty 0:eb53bdf2b7eb 139 s=0;
cdupaty 0:eb53bdf2b7eb 140 cmd[0]=0x24; // First byte of PWM data
cdupaty 0:eb53bdf2b7eb 141 s++;
cdupaty 0:eb53bdf2b7eb 142 // copy img buffer to IS31FL3731
cdupaty 0:eb53bdf2b7eb 143 for(uint8_t j=0; j<144; j++)
cdupaty 0:eb53bdf2b7eb 144 {
cdupaty 0:eb53bdf2b7eb 145 cmd[j+1]=img[j];
cdupaty 0:eb53bdf2b7eb 146 s++;
cdupaty 0:eb53bdf2b7eb 147 #ifdef debug
cdupaty 0:eb53bdf2b7eb 148 printf("j= %d img[j]= %d \n",j,img[j]);
cdupaty 0:eb53bdf2b7eb 149 #endif
cdupaty 0:eb53bdf2b7eb 150 }
cdupaty 0:eb53bdf2b7eb 151 Wire.write(I2C_ADDR,cmd,s);
cdupaty 1:81948520c7ed 152 wait_ms(30); // can be adjuted for speed annimation
cdupaty 0:eb53bdf2b7eb 153 }
cdupaty 0:eb53bdf2b7eb 154
cdupaty 0:eb53bdf2b7eb 155 int main()
cdupaty 0:eb53bdf2b7eb 156 {
cdupaty 1:81948520c7ed 157 #ifdef debug
cdupaty 1:81948520c7ed 158 printf("-------------------------------------------------------------\n");
cdupaty 1:81948520c7ed 159 printf("printf("Simulation flame with IS31FL3731\n\n");
cdupaty 1:81948520c7ed 160 printf("-------------------------------------------------------------\n");
cdupaty 1:81948520c7ed 161 #endif
cdupaty 1:81948520c7ed 162 // arduino like
cdupaty 0:eb53bdf2b7eb 163 setup();
cdupaty 1:81948520c7ed 164 while(1) loop();
cdupaty 0:eb53bdf2b7eb 165 }