[Solved] Modify colorshield.h to work with Arduino Leonardo

Hi,

I tried to modify the colorshield lib from Colorduino Library for Arduino – Lincomatic's DIY Blog to work with the Leonardo but I didn't get the part from the void TC to work. I tried some coding but I lost my Board often. I think the Timer/Counter 4 is connectet with the USB Interface sometimes the PC can't remember what it is so I have to burn the Bootloader again. There is my code.

/*
  Colorduino - Colorduino Library for Arduino
  Copyright (c) 2011-2012 Sam C. Lin <lincomatic@hotmail.com>
  based on C code by zzy@iteadstudio...
*/
#ifndef _COLORDUINO_H_
#define _COLORDUINO_H_

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"
#else
#include "WProgram.h"
#endif

#include <avr/pgmspace.h> 
#include <avr/io.h>
#include <avr/interrupt.h>

#define ColorduinoBitsPerColor 8

#define ColorduinoScreenWidth 8
#define ColorduinoScreenHeight 8

/*****************************
define the IO
*****************************/
//#define RST_BIT 0x04
//#define LAT_BIT 0x02
//#define SLB_BIT 0x01
//#define SCL_BIT 0x40
//#define SDA_BIT 0x80

#define RST_BIT digitalPinToBitMask(A2)
#define LAT_BIT digitalPinToBitMask(A1)
#define SLB_BIT digitalPinToBitMask(A0)
#define SCL_BIT digitalPinToBitMask(6)
#define SDA_BIT digitalPinToBitMask(7)

//#define RST PORTC
//#define LAT PORTC
//#define SLB PORTC
//#define SCL PORTD
//#define SDA PORTD

#define RST* portOutputRegister(digitalPinToPort(A0))
#define LAT* portOutputRegister(digitalPinToPort(A1))
#define SLB* portOutputRegister(digitalPinToPort(A2))
#define SCL* portOutputRegister(digitalPinToPort(6))
#define SDA* portOutputRegister(digitalPinToPort(7))


//#define open_line0	{PORTB=0x01;}
//#define open_line1	{PORTB=0x02;}
//#define open_line2	{PORTB=0x04;}
//#define open_line3	{PORTB=0x08;}
//#define open_line4	{PORTB=0x10;}
//#define open_line5	{PORTB=0x20;}
//#define open_line6	{PORTD=0x08;}
//#define open_line7	{PORTD=0x10;}
//#define close_all_lines	{PORTD=0x00;PORTB=0x00;}

#define open_line0	{*portOutputRegister(digitalPinToPort(8))=digitalPinToBitMask(8);}
#define open_line1	{*portOutputRegister(digitalPinToPort(9))=digitalPinToBitMask(9);}
#define open_line2	{*portOutputRegister(digitalPinToPort(10))=digitalPinToBitMask(10);}
#define open_line3	{*portOutputRegister(digitalPinToPort(11))=digitalPinToBitMask(11);}
#define open_line4	{*portOutputRegister(digitalPinToPort(12))=digitalPinToBitMask(12);}
#define open_line5	{*portOutputRegister(digitalPinToPort(13))=digitalPinToBitMask(13);}
#define open_line6	{*portOutputRegister(digitalPinToPort(3))=digitalPinToBitMask(3);}
#define open_line7	{*portOutputRegister(digitalPinToPort(4))=digitalPinToBitMask(4);}

#if defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
#define close_all_lines	{PORTB&=0b00001111;PORTG&=0b11101111;PORTE&=0b11101111;PORTH&=0b11001111;}
#elif defined(__AVR_ATmega32U4__)
#define close_all_lines	{PORTB&=0b00001111;PORTC&=0b01111111;PORTD&=0b11101110;}
#else
#define close_all_lines	{PORTB&=0b11000000;PORTD&=0b11000000;}
#endif

#define LED_RST_SET RST|=RST_BIT
#define LED_RST_CLR RST&=~RST_BIT
#define LED_SDA_SET SDA|=SDA_BIT
#define LED_SDA_CLR SDA&=~SDA_BIT
#define LED_SCL_SET SCL|=SCL_BIT
#define LED_SCL_CLR SCL&=~SCL_BIT
#define LED_LAT_SET LAT|=LAT_BIT
#define LED_LAT_CLR LAT&=~LAT_BIT
#define LED_SLB_SET SLB|=SLB_BIT
#define LED_SLB_CLR SLB&=~SLB_BIT

typedef struct pixelRGB {
  unsigned char r;
  unsigned char g;
  unsigned char b;
} PixelRGB;

class ColorduinoObject {
public:
  PixelRGB frameBuffer0[ColorduinoScreenWidth*ColorduinoScreenHeight];
  PixelRGB frameBuffer1[ColorduinoScreenWidth*ColorduinoScreenHeight];
  PixelRGB *curDrawFrame;
  PixelRGB *curWriteFrame;
  unsigned char line;

  ColorduinoObject() {
    line = 0;
    curWriteFrame = frameBuffer0;
    curDrawFrame = frameBuffer1;
  }

  void _IO_Init()
  {
    //DDRD = 0xff; // set all pins direction of PortD
    //DDRC = 0xff; // set all pins direction of PortC
    //DDRB = 0xff; // set all pins direction of PortB
    
    //PORTD = 0x00; // set all pins output is low of PortD
    //PORTC = 0x00; // set all pins output is low of PortC
    //PORTB = 0x00; // set all pins output is low of PortB
    
    uint8_t lines[] = {A0,A1,A2,3,4,6,7,8,9,10,11,12,13};
    
    for(int i = 0; i < 13;i++){
    	pinMode(lines[i],OUTPUT);
    	digitalWrite(lines[i],LOW);
   	}
  }
  
  void LED_Delay(unsigned char i);
  
  void SetWhiteBal(unsigned char wbval[3]);

  void _LED_Init()
  {
    LED_RST_SET;
    LED_Delay(1);
    LED_RST_CLR;
    LED_Delay(1);
    LED_RST_SET;
    LED_Delay(1);
    
    line = 0;
  }

  void _TC2_Init()
  {
  // Arduino runs at 16 Mhz...
  // Timer Settings, for the Timer Control Register etc. , thank you internets. ATmega168 !
  // Timer2 (8bit) Settings:
  // prescaler (frequency divider) values:   CS22    CS21   CS20
  //                                           0       0      0    stopped
  //                                           0       0      1      /1 
  //                                           0       1      0      /8 
  //                                           0       1      1      /32
  //                                           1       0      0      /64 
  //                                           1       0      1      /128
  //                                           1       1      0      /256
  //                                           1       1      1      /1024
  // TCNT2 increments every  = 16MHz / prescaler
    
    #if defined (__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)
   TCCR2B = 0x00; // Disable timer while configuring
    TCCR2A = 0x00; // Use normal mode
    TIMSK2 = 0x01; // Timer2 overflow interrupt enable
    TCNT2 = 0xff; // Reset timer to count of 255
    TCCR2B = 0x05; // Prescaler = 128	
    #elif defined(__AVR_ATmega32U4__)
    // set prescaler to 128 -> TCNT2 freq = 125KHz
    TCCR4B |= (1<<CS43);
    TCCR4B &= ~((1<<CS42)|(1<<CS41)|(1<<CS40));
    
  //  TCCR4C &= ~(1<<PWM4D);
  //  TCCR4D &= ~((1<<WGM41)|(1<<WGM40));   // Use normal mode
    TCCR4A &= ~((1<<COM4A1)|(1<<COM4A0));		// Use normal mode
  //  ASSR |= (1<<AS2);       // Use internal clock - external clock not used in Arduino
  //  TIMSK4 |= (1<<TOIE4);      //Timer4D Overflow Interrupt Enable
    TIFR4 |= (1<<TOV4);
    TCNT4 = 0xff;
		#else
    // set prescaler to 128 -> TCNT2 freq = 125KHz
    TCCR2B |= ((1<<CS22)|(1<<CS20));
    TCCR2B &= ~((1<<CS21));   

    TCCR2A &= ~((1<<WGM21) | (1<<WGM20));   // Use normal mode
    ASSR |= (1<<AS2);       // Use internal clock - external clock not used in Arduino
    TIMSK2 |= ((1<<TOIE2) | (0<<OCIE2B));   //Timer2 Overflow Interrupt Enable
    TCNT2 = 0xff;
		#endif
		sei();
  }
  
  void open_line(unsigned char x)
  {
    switch (x)
      {  
      case 0 :open_line0;
	break;
      case 1 :open_line1;
	break;
      case 2 :open_line2;
	break;
      case 3 :open_line3;
	break;
      case 4 :open_line4;
	break;
      case 5 :open_line5;
	break;
      case 6 :open_line6;
	break;
      case 7 :open_line7;
	break;
      default: close_all_lines;
	break;
      }
  }

  void Init() {
    _IO_Init();           //Init IO
    _LED_Init();          //Init LED Hardware
    _TC2_Init();          //Init Timer/Count2
  }

  void FlipPage() {
    cli();
    // swap frame buffers
    PixelRGB *tmp = curDrawFrame;
    curDrawFrame = curWriteFrame;
    curWriteFrame = tmp;
    sei();
  }

  // get a pixel for writing in the offscreen framebuffer
  PixelRGB *GetPixel(unsigned char x,unsigned char y) {
    return curWriteFrame + (y * ColorduinoScreenWidth) + x;
  }

  // get a pixel from the active framebuffer
  PixelRGB *GetDrawPixel(unsigned char x,unsigned char y) {
    return curDrawFrame + (y * ColorduinoScreenWidth) + x;
  }

  // set a pixel in the offscreen frame buffer
  void SetPixel(unsigned char x, unsigned char y, unsigned char r, unsigned char g, unsigned char b)
  {
    PixelRGB *p = GetPixel(x,y);
    p->r = r;
    p->g = g;
    p->b = b;
  }

  void run();
};

extern ColorduinoObject Colorduino;

#endif // _COLORDUINO_H_

Inserting the Arduino Mega parts vom Akto.

Did someone know how to use Timer/Counter4 right?

The Code below show some of my tests with several registers around the PLL and the possible frequences I get.

void setup() {
    pinMode(6,OUTPUT);
    analogWrite(6,127);
    TCCR4E = 0x0;
    TCCR4D = 0x0;
    TCCR4B = 0b000001;
//    PLLFRQ = 0b00000100;    //62kHz
//    PLLFRQ = 0b00100100;    //125kHz
//    PLLFRQ = 0b01101010;    //250kHz
    PLLFRQ = 0b01011010;    //375kHz
}
void loop() {}

BTW. I make no changes on the ISR(TIMER2_OVF_vect)

Works!!!

Needed to change the Timer and some registers there are the new files for the Arduino Mega, and the Arduino Leonardo

Colorduino.cpp (3.89 KB)

Colorduino.h (8.21 KB)

Hi there

does the Colorduino not natively work with the Leonardo.
I also have a leonardo and i cannot get plasma to work.

All I have is R to G to B every second which I guess is the demo code?

I have tried replacing the library with your modified one but it still doesnt work.
What Timer and Register do I have to change?
I have no idea what this means

any help you could give me would be great
thanks

Vahakn