Shift PWM

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

Arduino Lithne
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)

Arduino Lithne
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

Changes Made

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.


Wire Library

Wire Library from Wire for Akafuino: I2C protocol changes

In this document, I will explain the changes that it was made in Xmegaduino Wire library to it works with Lithne board.

The first change was related to the endTransmission() behavior. This function worked in the opposite way of Arduino Wire library: when you send false, you send a “Stop sequence” and true meant “Repeated Start”. So, I just changed the behavior, so it could work as Arduino.

The second change was made just to avoid future problems: the endTransmission() worked with the address in this line:

this->slaveAddress=slaveAddress << 1;

The problem is the function endTransmission doesn’t receive slaveAddress value, so, if we call the function twice, without upload the address, we would have sent the wrong address. So, this line was moved to the beginTransmission() function.

The third change is related to the behavior of the TWI protocol and the ATXMEGA. When we want to send a repeated start in the bus, we should call the function: endTransmission(false). So, in onMasterInterrupt(), it was treated in the following part:

else if(!slaveReadSize) {
/*
we wrote out all the data, but user also wants a
repeated start condition
*/
twi->MASTER.ADDR=this->slaveAddress | 0x01;
}
else {
/*
we are finished writing and have no pending read
send stop and thats it
*/
twi->MASTER.CTRLC=TWI_MASTER_CMD_STOP_gc;
twiResult=TWI_SUCCESS;
}

The first bold line was changed and it is related to the first change it was made (opposite behavior in comparison with Arduino). The second bold line is the repeated start function: when we change the value of MASTER.ADDR, but the bus is already owned, it sends a repeated start. The problem is that after this, the I2C protocol automatically sends the address again, now requesting data. So, the slave starts to send data even if the master is not “ready” for that. After sending the first data, the interruption is called again, but we still didn’t upload the value of slaveReadSize in requestFrom() and the function “thinks” we are not requesting data and sends a NACK and a stop sequence.

After an attentive reading to the datasheet and user manual, I discovered a different way to send the repeated start function, letting requestFrom() ask for data. The change is showed below.

twi->MASTER.CTRLC = 0x01; //repeated start

twi->MASTER.STATUS = 0x01;  //idle mode

Capacitive Sensor Library

Based on Capacitive Sensing Library for Arduino

This library had several issues and I will explain the changes I made here.

The first issue was related to the Register Data Type. XMEGA uses 16 bits while Arduino only 8. So I changed the following line in the header file:

#define REGISTER_DATA_TYPE uint8_t*

I change to something like “if it is XMEGA, make it 16 bits”. After that the program starts to compile, but it doesn’t work at all and I could only imagine the problem was in the bit mask. In the CapacitiveSensorDue function, there are several lines to make the bit mask and save it in the class. Basically, I “removed” everything from the Lithne code and start it again with a “#if defined(__AVR_XMEGA__)”. All the code I added is inside this if functions. I also created some definitions and other variables to make the code more clear.

After those changes, the library was still not working. I did some code analyzing and notice that the behavior of I/O registers is different in XMEGA. So, again, in the senseSample function, I “removed” everything and restarted. What the code is doing is setting the receiver pin LOW, turning off the pull resistors, setting the sender HIGH and then counting the time to the receiver becomes HIGH also. After that, it turns the receiver HIGH and the sender LOW and counting again the time to the transmitter becomes LOW. If you touch the wire/foil, the time to the receiver becomes HIGH is much bigger.

I tested the capacitive sensor with a resistor of 1M ohms and a capacitor of 100pF and it works pretty well, returning values between almost 0 and approximately 4000, but with 10M ohms resistor, it doesn’t work, because it was counting too much.