Back to Blinky

In this post I describe the trials an tribulations of bringing up my Timed LED Lighting Controller and how I went about implementing my first I²C Slave Driver for the ATTiny20.

I was keen to receive the boards for the Timed LED Lighting controller to know if they would fit in the chosen housing. The boards arrived and to my delight, they fitted perfectly. So the exercise of printing out the board paid off. Now it is time for the real test – assembly and bringing the boards up.

img_0547

wrongpins_eThe assembly was not too challenging and went fairly quickly. In bringing the board up, I discovered a few problems. The first was the classic “Wong pins” issue. I had hoped that this issue would not be a problem from my past experiences, but it still managed to slip through, though I am not sure how. Anyhow,  I consider this a prototype i.e on PCB instead of breadboard and so a bit of component yoga sorted that issue out.

Bringing up the Board

The board is now operating with the power indicators glowing. The next and biggest part is proving that the ATTiny20 is alive. My usual technique for this is to use my AVRISP Mk II and the Atmel Studio (version 7). Under “Device Program” (Ctrl-Shift-P) there is a dialogue where I can chose the Tool and the device, interface and then I can read the device signature. If this operation works, then I know the controller is alive and well.

atmel_device_programming_dialog

Unfortunately, in this case – nothing. I was perplexed. I have assembled quite a few boards, mostly with Atmel controllers and this is the first time I have not been able to reach the controller first time.

Reading the Datasheet

This issue has me reflecting over the many times I have heard the more experienced people say how important it is to read the data sheet and how they have all been caught out at one time or another. This message has now been bought home. There were two aspects I completely overlooked. In hind-sight it is not so much as not reading the Datasheet but not knowing what to read in the Datasheet.

Going back to the Datasheet, I suddenly noticed “Programming Voltage 5V”. When selecting the controller, all I was looking at was the Operating Voltage and did not consider the programming voltage at all! So a quick check through my stock (see my previous blog), found a suitable 5V LDO that would be compatible with the design I have for the 3.3V just to try it out – Still no luck. The ATTiny20 was not talking.

When faced with problems like this, I feel it is best to go back to a known position. This means to connect a board that does work. In doing this, something suddenly clicked. the Device drop down on the Device Programming dialogue showed ISP. Whereas, the ATTiny20 shows TPI. Suddenly I thought, “What’s TPI?”. Once again, the Datasheet explains it all There is a whole chapter dedicated to the Tiny Programming Interface (TPI). The model I was used to with the ATMega controllers was the SPI type setup with MOSI, MISO, CLK, ~RESET, Vcc and GND. TPI only uses 5 pins and for the ATTiny20, it does not use the pins allocated for SPI. The turns out to be a huge oversight simply because I assumed the SPI configuration and was not looking for anything different. For the prototype, it was not a tragedy since I have exposed all spare pins to headers on the off chance that I might want to use them.

So connecting the AVRISP MkII in the TPI configuration with a 5V supply to the chip, suddenly it was visible and now able to be programmed.atmel_device_programming_dialog_ok

I²C Finding a Starting Point

This would be my first attempt with programming an Atmel micro controller in C. Previously I have used BASCOM which takes a lot of the ground work from setting up and using functions like SPI and I²C. This time, I wanted to get a bit closer to the actual registers of the controller. Only I had not anticipated how close I would have to go with the selection of the ATTiny20.

Before jumping into coding for I²C, I decided the best starting point would be getting back to blinky using the TIMER functions of the controller. This was a good introduction into reading this section of the data sheet to understand how to work with the registers to get a LED flashing. A snipped from the code is shown below.

int main(void)
{
   TCCR0A = 0;                  // Reset the operation
   TCCR0A |= ( 1 << WGM01 );    // CTC operation
   TCCR0B |= ( 5 << CS00 );     // 1024 Pre-scaler
   OCR0A = startValue;          // Set the start value
   TIMSK |= ( 1 << OCIE0A );    // Enable the interrupt on OCR0A

   PORTA &= ~( 7 << PORTA0 );

   sei();                       // Enable all interrupts

   while (1) 
   {
      if( led_flag){
         led_flag = 0;
         PORTA ^= (1 << LED);
      }
   }
}

/* Interrupt Service Routine for Timer0)
ISR(TIM0_COMPA_vect) {
   led_flag = 1;
}

Next was I²C. This ended up being a little more than I had expected or wanted for a first attempt. Firstly was the terminology. For what I have found out for licensing reasons, I²C is referred to as Twin Wire Interface (TWI) in the Atmel world. The second was there is no library (that I could find) for TWI on the ATTiny20. There are reference for the other ATTiny controllers. The difference being, the ATTiny I²C module can only implement the Slave, where as most others can act as both Master or  Salve. So the given examples were based a different set of registers to the ATTiny20.

I really had to find an in-road. So from the model shown in the Data sheet, I reached for my modelling application to try my hand at an Activity Diagram. From the data sheet, the trick being one interrupt but having to handle the various cases. Once I had a rough model, I started to see how I could make a start on this. This model is actually not complete as it does not cover the collision case but it is enough to get a start. The idea would be to build this up as time and need allows.

TWI-Activity_t

The full example is on my GitHub as it stands so far – as well as the board designs. The Interrupt service routine is bigger than what I would have liked but since this slave has a fixed task, I don’t think this should be a big problem as it would be for other applications. Because I only have 2K of Flash to work with on the ATTiny20, it was easier and more prudent to integrate the slave register setup directly in the I²C driver rather than having a more abstract model. To this end I could implement what I had previously specified in my data-sheet in about 1700 bytes or 87% of the flash.

Conclusion

There were a couple of lessons and ideas to come away with for this stage of the project. Although the more experienced of us will tell us to read the data sheet – it takes experience to know what to look for when reading the data sheet. The other tip is to go back to basics – even if it is not 100% related to the problem at hand. It will give the right context to move forward in the actual problem domain and thirdly, don’t under estimate the effort needed to use some type of model. It does not matter if it is flow chart, activity diagram or pseudo code. It all helps to organise a problem into a tangible solution. My activity diagram is not complete, especially in comparison to the final code, but it provided me with the in-road I needed to get things started.

The adventure does not stop here. Once I had the basic working model of the slave, I started to test it on its final platform – A Raspberry Pi. I will talk about this in another article with the integration of this with Python and Django.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s