First of all, the initialization of the timers should be changed. It is well commented, so I guess it is not complicate.
- In void CShiftPWM::Start(int ledFrequency, unsigned char maxBrightness), there is a lot of definitions of the SPI protocol. It has to be changed because nothing was defined for Lithne. It will be hard…
- In void CShiftPWM::PrintInterruptLoad(void), there are more uses of the Timer’s registers. It has to be changed also.
- The function that handles the interruptions should be changed, because it also has definitions that Lithne doesn’t have (for bitmasking).
- Changed all the SPI register definitions and imitate the same behavior of Arduino. It works!
- Changed the timer definitions and also the working mode, because CTC mode is not available for XMEGA. It works!
- Changed the bitmasking for the Latch pin and also for clock and data pins, in case the user doesn’t want to use SPI communication
- Pins for the SPI communication in pins_arduino.h for Lithne board (from 30, 31, 32, 33 to 28, 29, 30, 31) because it was wrong.
Table 1 – Changes in SPI registers
|SPCR |= _BV(DORD);||SPI.CTRL |= 0x20;|
|SPCR = (SPCR & 0b11111000);||SPI.CTRL &= 0b11111000;|
|SPSR = (SPSR & 0b11111110);||SPI.CTRL &=0b01111111;|
|SPCR |= _BV(CPOL);SPCR |= _BV(CPHA);||SPI.CTRL |= 0x0C; //turn mode bits on|
|SPCR |= _BV(MSTR);||SPI.CTRL |= 0x10;|
|SPCR |= _BV(SPE);||SPI.CTRL |=0x40;|
|while (!(SPSR & _BV(SPIF)));||while(!(SPI.STATUS & 0x80)); //interrupt flag|
|SPDR = sendbyte; // Send the byte to the SPI||SPI.DATA = sendbyte; //Send the byte to the SPI|
Unfortunately, XMEGA clocks don’t have the CTC mode, used in the library, so I will have to try to “imitate” the mode.
Table 2 – Changes in timer registers (using normal mode)
|bitSet(TCCR1B,WGM12);bitClear(TCCR1B,WGM13);bitClear(TCCR1A,WGM11);bitClear(TCCR1A,WGM10);||TCB0.CTRLB = 0x03; //Single Slope mode|
|bitSet(TCCR1B,CS10);bitClear(TCCR1B,CS11);bitClear(TCCR1B,CS12);||TCB0.CTRLA = 0b00000001; //prescaler of 1|
|OCR1A = round((float) F_CPU/((float) m_ledFrequency*((float) m_maxBrightness+1)))-1;||TCB0.PER = (round((float) F_CPU/((float) m_ledFrequency*((float) m_maxBrightness+1)))-1);|
|bitSet(TIMSK1,OCIE1A);||TCB0.INTCTRLA = 0b00000001; //enable interruptTCB0.INTFLAGS = 0b00000001; //clear flag|
You can see all the changes made looking for #if defined(__AVR_XMEGA__) in the code. I don’t know if it is easy to understand, so it will be more commented.
I’m also having a problem with the Timer: it doesn’t accept when I use TCB0. I’m using TCD0 in place, but it is the same that I used for Servo library. I will try to use another timer. It was because TCB0 doesn’t exist. I changed to TCE0 (I guess it was not used yet).
The library is working now and looks like it has the same behavior of Arduino. Need to be more tested. The only issue is that I still don’t know why it works slower than Arduino. Lithne took more 3min33sec to compile the “RGB.example” code while Arduino Uno took 1min26sec.