Finally got it working. yay!
Issue was related with wiring and an interesting thing, Once deployment if board not disconnected, the chip was betting a weird behavior.
Modified Tlc5940.cs to allow cascading chips:
using Microsoft.SPOT.Hardware;
using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;
using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using SmudgeIT.Tlc5940;
using Gadgeteer.Modules.GHIElectronics;
namespace CerbuinoBee
{
public class Pins
{
public const Cpu.Pin D0 = (Cpu.Pin)0x1B; // PB11/I2C2_SDA/UART3_RX
public const Cpu.Pin D1 = (Cpu.Pin)0x1A; // PB10/I2C2_SCL/SPI2_SCK/UART3_TX
public const Cpu.Pin D2 = (Cpu.Pin)0x1C; // PB12/CAN2_RX
public const Cpu.Pin D3 = (Cpu.Pin)0x2E; // PC14/XO32
public const Cpu.Pin D4 = (Cpu.Pin)0x2F; // PC15/XI32
public const Cpu.Pin D5 = (Cpu.Pin)0x08; // PA8/MC01/PWM
public const Cpu.Pin D6 = (Cpu.Pin)0x0A; // PA10/LOADER1U2/PWM
public const Cpu.Pin D7 = (Cpu.Pin)0x24; // PC4/ADC12_IN14
public const Cpu.Pin D8 = (Cpu.Pin)0x1D; // PB13/SP2_SCK/CAN2_TX/PWM
public const Cpu.Pin D9 = (Cpu.Pin)0x09; // PA9/VBUS
public const Cpu.Pin D10 = (Cpu.Pin)0x0F; // PA15/J_TDI/PWM/SP1_SSEL
public const Cpu.Pin D11 = (Cpu.Pin)0x15; // PB5/CAN2_RX/PWM/SP1_MOSI
public const Cpu.Pin D12 = (Cpu.Pin)0x14; // PB4/J_TRST/PWM/SP1_MISO
public const Cpu.Pin D13 = (Cpu.Pin)0x13; // PB3/J_TDO/PWM/SPI1_SCK
public const Cpu.Pin A0 = (Cpu.Pin)0x11; // PB1/ADC12_IN9
public const Cpu.Pin A1 = (Cpu.Pin)0x05; // PA5/SPI1_SCK/ADC12_IN5/DAC2
public const Cpu.Pin A2 = (Cpu.Pin)0x10; // PB0/ADC12_IN8
public const Cpu.Pin A3 = (Cpu.Pin)0x23; // PC3/ADC123_IN13/SPI2_MOSI
public const Cpu.Pin A4 = (Cpu.Pin)0x21; // PC1/ADC123_IN11
public const Cpu.Pin A5 = (Cpu.Pin)0x04; // PA4/SP1_SSEL/ADC12_IN14/DAC1
public const Cpu.Pin LED = (Cpu.Pin)0x12; // PB2/BOOT1
public const Cpu.Pin SDDetect = (Cpu.Pin)0x22; // SD Detect
}
}
// <copyright file="Tlc5940.cs" company="Dave Smith">
//
// Copyright (C) 2010 Dave Smith http://dotnetdave.net
//
// This file is part of the TLC5940 driver for Netduino.
// The TLC5940 driver for Netduino is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// The TLC5940 driver for Netduino 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 General Public License for more details.
// You should have received a copy of the GNU General Public License
// along with the TLC5940 driver for Netduino. If not, see http://www.gnu.org/licenses/.
// </copyright>
// <summary>
// Driver for the TI TLC 5490 written for the Netduino
//
// Email: TLC5490@ dotnetdave.net
// </summary>
namespace SmudgeIT.Tlc5940
{
using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
/// <summary>
/// Driver for the TI TLC5940
/// </summary>
public class Tlc5940
{
/// <summary>
/// Max Value for the pin
/// </summary>
private const int GlcCounterMax = 4096;
/// <summary>
/// The port for the SCLK pin
/// </summary>
private OutputPort sclk;
/// <summary>
/// The port for the SIN pin
/// </summary>
private OutputPort sin;
/// <summary>
/// The port for the BLANK pin
/// </summary>
private OutputPort blank;
/// <summary>
/// The port for the XLAT pin
/// </summary>
private OutputPort xlat;
/// <summary>
/// The port for the VPROG pin
/// </summary>
private OutputPort vprog;
/// <summary>
/// The port for the GCCLK pin
/// </summary>
private OutputPort gcclk;
/// <summary>
/// The port for the BLANK pin
/// </summary>
private int[] dotcorrection;
/// <summary>
/// Brightness data
/// </summary>
private int[] bright;
/// <summary>
/// Is this the first cycle
/// </summary>
private bool firstCycle = true;
/// <summary>
/// Counter for the GLCCLK pin
/// </summary>
private int glcCounter = 1;
/// <summary>
/// Gets or sets the dot correction values.
/// </summary>
/// <value>The dot correction values.</value>
public int[] DotCorrectionValues
{
get { return this.dotcorrection; }
set { this.dotcorrection = value; }
}
/// <summary>
/// Gets or sets the grayscale color values.
/// </summary>
/// <value>The grayscale color values.</value>
public int[] GrayscaleColorValues
{
get { return this.bright; }
set { this.bright = value; }
}
/// <summary>
/// Initializes a new instance of the <see cref="Tlc5940"/> class.
/// </summary>
/// <param name="sclkPin">The SCLK pin.</param>
/// <param name="sinPin">The SIN pin.</param>
/// <param name="blankPin">The BLANK pin.</param>
/// <param name="xlatPin">The XLAT pin.</param>
/// <param name="vprogPin">The VPROG pin.</param>
/// <param name="gcclkPin">The GCCLK pin.</param>
public int NumChips;
public Tlc5940(
Cpu.Pin sclkPin,
Cpu.Pin sinPin,
Cpu.Pin blankPin,
Cpu.Pin xlatPin,
Cpu.Pin vprogPin,
Cpu.Pin gcclkPin,
int _NumChips)
{
NumChips = _NumChips;
this.sclk = new OutputPort(sclkPin, false);
this.sin = new OutputPort(sinPin, false);
this.blank = new OutputPort(blankPin, true);
this.xlat = new OutputPort(xlatPin, false);
this.vprog = new OutputPort(vprogPin, true);
this.gcclk = new OutputPort(gcclkPin, false);
this.bright = new int[16 * _NumChips];
this.dotcorrection = new int[16 * _NumChips];
this.DotCorrectionValues = new int[16 * _NumChips];
for (int index = 0; index < 16 * _NumChips; index++)
{
this.bright[index] = 0x800;
this.dotcorrection[index] = 0x20;
this.DotCorrectionValues[index] = 10;
}
}
/// <summary>
/// Inits this instance.
/// </summary>
public void Init()
{
this.LoadDCValues();
this.vprog.Write(false);
}
/// <summary>
/// Sets all the outputs to the brightness value.
/// </summary>
/// <param name="brightness">The brightness.</param>
public void SetAll(int brightness)
{
if (brightness > 0 || brightness < 101)
{
for (int i = 0; i < 16*NumChips; i++)
{
this.Set(i + 1, brightness);
}
}
}
/// <summary>
/// Clears all the outputs.
/// </summary>
public void Clear()
{
for (int i = 0; i < 16*NumChips; i++)
{
this.Set(i + 1, 0);
}
}
/// <summary>
/// Sets the specified channel.
/// </summary>
/// <param name="channel">The channel.</param>
/// <param name="brightness">The brightness.</param>
public void Set(int channel, int brightness)
{
if (channel < 1 || channel > 16 * NumChips || brightness < 0 || brightness > 101)
{
throw new ApplicationException("Bad Boy");
}
this.bright[channel - 1] = (int)System.Math.Ceiling(brightness * 20.48);
}
/// <summary>
/// Updates this instance.
/// </summary>
public void Update()
{
this.LoadBrightValues(this.firstCycle);
}
/// <summary>
/// Loads the DC values.
/// </summary>
private void LoadDCValues()
{
this.vprog.Write(true);
for (int i = 15*NumChips; i >= 0; i--)
{
for (int j = 0x20; j != 0; j >>= 1)
{
if ((this.dotcorrection[i] & j) == 0)
{
this.sin.Write(false);
}
else
{
this.sin.Write(true);
}
this.PulsePort(this.sclk);
}
}
this.PulsePort(this.xlat);
}
/// <summary>
/// Loads the bright values.
/// </summary>
/// <param name="first">if set to <c>true</c> [first].</param>
private void LoadBrightValues(bool first)
{
this.blank.Write(false);
for (int i = 15*NumChips; i >= 0; i--)
{
for (int j = 0x800; j != 0; j >>= 1)
{
if ((this.bright[i] & j) == 0)
{
this.sin.Write(false);
}
else
{
this.sin.Write(true);
}
this.PulsePort(this.sclk);
this.PulsePort(this.gcclk);
this.glcCounter++;
}
}
while (this.glcCounter < Tlc5940.GlcCounterMax*NumChips)
{
this.PulsePort(this.gcclk);
this.glcCounter++;
}
this.blank.Write(true);
this.PulsePort(this.xlat);
if (first)
{
this.PulsePort(this.sclk);
this.firstCycle = false;
}
}
/// <summary>
/// Pulses the port.
/// </summary>
/// <param name="port">The port to set.</param>
private void PulsePort(OutputPort port)
{
port.Write(true);
port.Write(false);
}
}
}
Testing program…
using System;
using System.Collections;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;
using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules;
using SmudgeIT.Tlc5940;
using Gadgeteer.Modules.GHIElectronics;
namespace TCL5940NT
{
public partial class Program
{
private static SmudgeIT.Tlc5940.Tlc5940 chip;
private SPI.Configuration _config;
private SPI _spi = null;
private byte[] _greyScaleBuffer = null;
void ProgramStarted()
{
Debug.Print("TCL5940 Testing");
int NumChips = 4;
//Cerbuino Bee pins
chip = new SmudgeIT.Tlc5940.Tlc5940(
(Cpu.Pin)19, //PB3 - SCLK -> 13 | Chip Pin 17
(Cpu.Pin)21, //PB5 - SIN -> 11 | Chip Pin 26
(Cpu.Pin)15, //PA15 - BLANK -> 10 | Chip Pin 23
(Cpu.Pin)9, //PA9 - XTAT -> D9 | Chip Pin 24
(Cpu.Pin)29, //PB13 - VPROG -> D8 | Chip Pin 27
(Cpu.Pin)46, //PC14 - GCCLK -> D3 | Chip Pin 25
NumChips
);
chip.Init();
char_Display.SetBacklight(true);
Random rnd = new Random();
chip.Clear();
//I know...while true........it's just for testing purpose :)
while (true)
{
for (int StartPin = 1; StartPin <= 16; StartPin++)
{
for (int Chan = StartPin; Chan <= 16 * NumChips; Chan += 1)
{
chip.Update();
chip.SetAll(0);
char_Display.CursorHome();
char_Display.Clear();
char_Display.PrintString("CH: " + Chan.ToString());
chip.Set(Chan, 100);
chip.Update();
}
for (int Chan = 16 * NumChips; Chan > StartPin; Chan -= 1)
{
chip.Update();
chip.SetAll(0);
char_Display.CursorHome();
char_Display.Clear();
char_Display.PrintString("CH: " + Chan.ToString());
chip.Set(Chan, 100);
chip.Update();
}
for (int Chan = StartPin; Chan <= 16 * NumChips; Chan += 2)
{
chip.Update();
chip.SetAll(0);
char_Display.CursorHome();
char_Display.Clear();
char_Display.PrintString("CH: " + Chan.ToString());
chip.Set(Chan, 100);
chip.Update();
}
for (int Chan = 16 * NumChips; Chan > StartPin; Chan -= 2)
{
chip.Update();
chip.SetAll(0);
char_Display.CursorHome();
char_Display.Clear();
char_Display.PrintString("CH: " + Chan.ToString());
chip.Set(Chan, 100);
chip.Update();
}
for (int Chan = StartPin; Chan <= 16 * NumChips; Chan += 3)
{
chip.Update();
chip.SetAll(0);
char_Display.CursorHome();
char_Display.Clear();
char_Display.PrintString("CH: " + Chan.ToString());
chip.Set(Chan, 100);
chip.Update();
}
for (int Chan = 16 * NumChips - StartPin; Chan > StartPin; Chan -= 3)
{
chip.Update();
chip.SetAll(0);
char_Display.CursorHome();
char_Display.Clear();
char_Display.PrintString("CH: " + Chan.ToString());
chip.Set(Chan, 100);
chip.Update();
}
chip.Update();
chip.SetAll(0);
for (int a=1;a<=NumChips;a++){
int pin = StartPin * a;
if (pin==0)
pin=1;
chip.Set(pin, 100);
}
chip.Update();
}
}
}
}
}
I got this working, although, couldn’t make the one from Mark Stevens Blog to work.
Thanks a lot for the help Brett.
Small demo