SAMD21 - I2C - write to multiple register addresses

Go To Last Post
29 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello everyone,

 

i'm using a SAMD21 Xplained Pro Eval Board trying to get I2C (Callback mode) working.

I have to initialise a few registers of a DAC-chip over I2C. Therefore I used the ASF I2C (Callback) example. But it's just possible to specify the address of the chip, but not of the registers.

I tried to send the address of the register always as first data byte and the data itself as second byte, but it seems not to run, although the procedure should be OK.

Is there a working way to write data to several registers of a device ?

 

That's the code i tried (modified ASF example):

#include <asf.h>
#include <system_interrupt.h>

void i2c_write_complete_callback(struct i2c_master_module *const module);
void configure_i2c(void);
void configure_i2c_callbacks(void);

//! [packet_data]
#define DATA_LENGTH 2

//! [address]
#define SLAVE_ADDRESS 0x36

//Register Addresses
#define TRIM_OSC   0x1B
#define SYSCTRLREG2 0x05
#define MASTER_VOL 0x07

// I/O-packets
struct i2c_master_packet wr_packet;
struct i2c_master_packet rd_packet;
// Init software module instance
struct i2c_master_module i2c_master_instance;

// [callback_func]
void i2c_write_complete_callback(
		struct i2c_master_module *const module)
{
	/* Initiate new packet read */
	// [read_next]
	i2c_master_read_packet_job(&i2c_master_instance,&rd_packet);
}

// [initialize_i2c]
void configure_i2c(void)
{
	// Initialize I2C module with defaults
	struct i2c_master_config config_i2c_master;
	i2c_master_get_config_defaults(&config_i2c_master);

	/* Change buffer timeout to something longer */
	config_i2c_master.buffer_timeout = 65535;
	
	#if SAMR30	//kann vermutlich wegfallen
		config_i2c_master.pinmux_pad0    = CONF_MASTER_SDA_PINMUX;
		config_i2c_master.pinmux_pad1    = CONF_MASTER_SCK_PINMUX;
	#endif

	/* Initialize and enable device with config */
	//! [init_module]
	while(i2c_master_init(&i2c_master_instance, CONF_I2C_MASTER_MODULE, &config_i2c_master)     \
			!= STATUS_OK);
	//! [enable_module]
	i2c_master_enable(&i2c_master_instance);
}

//! [setup_callback]
void configure_i2c_callbacks(void)
{
	/* Register callback function. */
	//! [callback_reg]
	i2c_master_register_callback(&i2c_master_instance, i2c_write_complete_callback,
			I2C_MASTER_CALLBACK_WRITE_COMPLETE);
	//! [callback_en]
	i2c_master_enable_callback(&i2c_master_instance,
			I2C_MASTER_CALLBACK_WRITE_COMPLETE);
}


int main(void)
{
	system_init();

	/* Configure device and enable. */
	configure_i2c();
	/* Configure callbacks and enable. */
	configure_i2c_callbacks();
	
	delay_init();

	uint8_t out_buffer[2];

	/* Init i2c packet. */
	//! [write_packet]
	wr_packet.address		= SLAVE_ADDRESS;
	wr_packet.data_length		= DATA_LENGTH;
	wr_packet.high_speed		= false;
	wr_packet.ten_bit_address	= false;
	
	//wait 50ms
	delay_ms(50);
	
	//Trim osc
	out_buffer[0] = TRIM_OSC;
	out_buffer[1] = 0x00;
	wr_packet.data = out_buffer;
	i2c_master_write_packet_job(&i2c_master_instance, &wr_packet);
	
	//wait 100ms
	delay_ms(100);
	
	//Exit sd
	out_buffer [0] = SYSCTRLREG2;
	out_buffer [1] = 0x00;
	wr_packet.data = out_buffer;
	i2c_master_write_packet_job(&i2c_master_instance, &wr_packet);

	//wait 50ms
	delay_ms(50);
        //set mv
	out_buffer [0] = MASTER_VOL;
	out_buffer [1] = 0x58;
	wr_packet.data = out_buffer;
	i2c_master_write_packet_job(&i2c_master_instance, &wr_packet);
	
	//wait 50ms
	delay_ms(50);
	
	//! [while]
	while (true) {

	}
}

I'll be thankful for some advice.

Greets Markus

This topic has a solution.
Last Edited: Sat. Feb 2, 2019 - 12:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

uSound wrote:
it's just possible to specify the address of the chip, but not of the registers.

That's because, as far as I2C is concerned, they are just data.

 

it seems not to run

What, exactly, do you mean by that?

 

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

uSound wrote:
a DAC-chip

What "DAC-chip", exactly?

Does the manufacturer not provide examples?

 

Post a link to the manufacturer's product page.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well it's not running because i can't hear anything out of my speakers smiley

To be precise it's a digital sourced class-D amp: TAS5713. Link: http://www.ti.com/lit/ds/symlink/tas5713.pdf

I already thought about the device address. Datasheet says the "7-bit address for the TAS5713 is 0011 011 (0x36)", which actually would be 8 bit.

Maybe i have to shift the 0x36 one to the right (0x1B) ?

With the original TI Eval Board of the Amp-chip everything is fine, so there is no fault in hardware or wireing.

 

Last Edited: Mon. Nov 20, 2017 - 12:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

uSound wrote:
Datasheet says the "7-bit address for the TAS5713 is 0011 011 (0x36)", which actually would be 8 bit.

No: it's seven - count them!

 

https://www.avrfreaks.net/comment...

 

https://www.avrfreaks.net/comment...

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil wrote:

uSound wrote:
Datasheet says the "7-bit address for the TAS5713 is 0011 011 (0x36)", which actually would be 8 bit.

No: it's seven - count them!

 

Quite confusing topic:

Of course "0011 011" is 7-bit. But the address is always a two digit hex value. So it's impossible to have just 7-bits.

"(0)0011 011" as binary = 1B in hex, but

0x36 in hex = 0011 0110 in binary.

 

The question is either, what the I2C-driver does. Does it shift the 8(!)-bit-address (0011 0110) one to the left and insert the R/W bit as LSB ?

 

 

Last Edited: Mon. Nov 20, 2017 - 05:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

uSound wrote:
the address is always a two digit hex value.

Well of course it is - you can never have part of a digit in any radix - can you?!

An I2C address most definitely is only 7-bits - that is clearly defined by the hardware.

If you want to write that number in Hex, then you obviously have to use 2 digits

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So the basic question is:

Do i have to use 0001 1011 or 0011 0110 to have the address set to 0x36, as the datasheet says ?

Being consequent, the second one should be the answer.

 

Edit:

Answered the question on my own:

The I2C-driver computes a binary OR from the address and the I2C_TRANSFER_WRITE (0). So 0011 0110 (0x36) is correct, as the datasheet says.

 

But still no sound from the speakers.

Last Edited: Mon. Nov 20, 2017 - 07:14 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't agree, when looking at the asf code I have

		i2c_module->ADDR.reg = (packet->address << 1) | I2C_TRANSFER_WRITE |
			(packet->high_speed << SERCOM_I2CM_ADDR_HS_Pos);

so I would pass 0x1b as the address. But I guess you already tried that by now.

/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Btw, "7-bit address for the TAS5713 is 0011 011 (0x36)" has to be the most confusing way to specify an I2C address I have ever seen (mainly because 0011 011 is not 0x36).

/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, 0x1B as address should be right. The sentence of the datasheet was the reason why i was struggling that much with the address.

Is it normal in I2C-drivers to shift the address one to the left ?

Well as you suggested, I tried 0x1B already. Doesn't work either.

I think it must be a quite easy issue, why the sound out doesn't work. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

uSound wrote:
Is it normal in I2C-drivers to shift the address one to the left ?

See  here: https://www.avrfreaks.net/comment...

By the time it ends up on the I2C wire, it has to have been shifted into the top 7 bits of  the first byte following the START condition.

Some libraries require you to supply it "ready shifted"; other do the shifting for you.

 

Both software library authors and hardware manufacturers are notorious in failing to explain this clearly and/or correctly.

 

angry 

 

 

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I already wondered that there are two different ways of implementing I2C on the SAMD21 in the Internet.

The one I used, which is the documentation of the ASF examples: http://www.atmel.com/Images/Atmel-42117-SAM-I2C-Bus-Driver-Sercom-I2C_ApplicationNote_AT03250.pdf

That one seems quite overloaded to me (lots of includes, headerfiles etc.). I mean I just want to send a few bytes over I2C.

 

The second one is much shorter: https://www.avrfreaks.net/sites/default/files/forum_attachments/Atmel-42631-SAM-D21-SERCOM-I2C-Configura.pdf

Is this implementation specially for the communication between 2 SAMs ?

 

Which one should I prefer to get I2C running on a SAMD21 with as little effort/code as possible ?

Last Edited: Sat. Nov 25, 2017 - 12:05 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If I want to send 0x05 at first and then 0x00, which byte must be at position 0 of the data buffer array ?

Do I have to do it this way:

out_buffer [0] = SYSCTRLREG2;
out_buffer [1] = 0x00;

or this way:

out_buffer [0] = 0x00;
out_buffer [1] = SYSCTRLREG2;

?

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

uSound wrote:
Is this implementation specially for the communication between 2 SAMs ?

No.

 

You need to understand that the microcontroller's I2C hardware neither knows nor cares what I2C Slave(s) you use; it just performs standard I2C operations - sends START condition, looks for ACK, sends bytes, receives bytes

 

Similarly, an I2C slave neither knows nor cares what I2C Host you use; all it sees are I2C bus actions - START condition, its address, etc

 

See: https://community.atmel.com/comm...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

uSound wrote:
two different ways of implementing I2C on the SAMD21

No, not 2 different ways: One seems to be a complete description of the entire SERCOM I2C functionality, the other is just the driver description for master mode only.

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello,

 

I'm back at that project again. I did the whole testing so far on an arduino which was totally easy to use. I solved the issue with the address: I took 0x36 and shifted one to the right. The driver shifts it back one to the left so the address is correct now.

Now I need so integrate the init sequence into an existing ASF project.

Is there any possibility to debug the i2c interface at runtime? Otherwise it would be just a try&error thing.

 

I focused on the code especially for the SAM D21 I suggested before: AT11628: SAM D21 SERCOM I2C Configuration for ATSAMD21J18 which should fit my Xplained Pro board. I'd prefer that solution instead of an asf example, because all components are compact in one file, that I could import in my target project.

I modified the code for only master transmission. I integrated the code from the AppNote in a basic ASF project for the Xplained Pro board. I'm using the 8 MHz onboard crystal for testing.

I attached the main.c and the conf.clocks-file.

 

I'm using the i2c standard mode with 100 kHz. For calculating the baudrate the datasheet says:

If BAUD.BAUDLOW is zero, BAUD will be used to generate both high and low periods of the SCL.
For more information on how to calculate the frequency, see “SERCOM I2C – SERCOM Inter-Integrated Circuit”
on page 511.

So I set BAUD.BAUDLOW to zero and calculated BAUD with the formula on page 517 (with T_Rise max = 300 ns):

f_baud  = ( fgclk / fscl ) - (( fgclk / 1000000) * 0.3 ) / 2 - 5
As result for fgclk = 8 MHz and fscl=100 kHz the BAUD would be 34 (rounded).

 

I'm using GCLK_GENERATOR_0, SERCOM0 (PA08=PAD0, PA09=PAD1). Everything compiles fine, though the init sequence doesn't work.

 

Could anyone have a look if there is any little mistake in the code or point out any debugging possibilities?

Thanks.

Kind regards,

Markus.

    

Attachment(s): 

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 1
tx_done = false;

is missing after the wait loops.

Also, depending on optimization setting, you might need volatile for all the globals shared with the ISR (for tx_buf that would be unexpected when using an AVR but it's possible it is needed here).

/Lars

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Lars,

 

I did the changes you mentioned, but that didn't solve the issue.

I don't get into the while (1) loop of the main function (can't turn the led on). If I comment the "i2c_master_send_bytes();" command, the program of course does nothing, but it runs into the while(1) loop and I'm able to flash the led.

So the program must hang inside of the i2c transmission command.

Do you have any further advice?

 

Greets, Markus

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This is odd, I tried it now in my SAMD21 Xplained Pro and I believe it performs as can be expected when there is no slave. Also the button works to light the LED.

I removed the delays here:

 

/Lars

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hmm, I also think that code should work. But it doesn't do in my case.

I checked it again with my Arduino Uno (with a level converter from 5V to 3V3) with the same wireing (uC board powers the 3V3 rail of the amp board). Works perfect. 

I measured the PA08 and PA09 pins of the Xplained board and they are at 3V3 (pullup) like it should be. I also checked the Vcc, which is also ok.

 

I also tested the polled and callback examples of the ASF, they also didn't work.

Just the I2C project from Atmel Start was working, but I can't migrate the AT Start project to my existing ASF project.

I think there must be something quite easy, what I'm overlooking.

Last Edited: Fri. Jan 4, 2019 - 10:10 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I managed to get the i2c working. Had some issues with soldering of the hardware.

I attached the working header file.

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I'm doing some work with i2c on the sam d21 again. As long term project I want to use a multimaster system. Therefore I switched to the i2c functions from the ASF.

I choose the sercom i2c master callback driver in the asf wizard.

The blocking version is working so far. My i2c send routine looks like that:

bool i2c_local_send_data(uint8_t dev_adr, uint8_t *data, uint8_t size)
{
	i2c_local_write_packet.address = dev_adr;
	i2c_local_write_packet.data_length = size;
	i2c_local_write_packet.data = data;

	//Write buffer to slave and send stop condition
	while (i2c_master_write_packet_wait(&i2c_local_module, &i2c_local_write_packet) != STATUS_OK)
	{
		//Increment timeout counter and check if timed out.
		if (timeout++ == MAX_TIMEOUTS) {
			return false;
		}
	}

	//reset timeout counter
	timeout = 0;

	return true;
}

As next step I need to use the non-blocking version of the i2c send. In ASF that would be the function "i2c_master_write_packet_job".

The examples in the app note concerning i2c asf driver show how to send data to a slave and read back the data in a callback.

I will have to do i2c reads of a few bytes while the system is running other functions. Therefore I need the non-blocking version.

At first I want to implement a simple send routine.

Now I'm thinking about how to implement that. I need to check if the data is send, to initiate the next transfer. What would be the best way to code that? Should I set a bool flag in the send callback and check it in the send routine with a while loop?

Or is it better to use the status_busy state of the i2c peripheral, for example wih "i2c_master_get_job_status"?

 

Kind regards, Markus

 

Last Edited: Fri. Feb 12, 2021 - 11:24 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

I did some tests and implemented the write functions as mentioned with a tx_done flag. The flag is set in the "I2C_MASTER_CALLBACK_WRITE_COMPLETE" callback. That is working perfectly.

bool i2c_local_write_data_nb(uint8_t dev_adr, uint8_t *data, uint8_t size)
{
	i2c_local_write_packet.address = dev_adr;
	i2c_local_write_packet.data_length = size;
	i2c_local_write_packet.data = data;

	//reset tx flag
	tx_done = false;

	//Init write transfer
	i2c_master_write_packet_job(&i2c_local_module, &i2c_local_write_packet);

	while (!tx_done);

	return true;
}

I then tried to do the read function the same way (with a rx_done flag). Therefore I wrote a function which does the write without stop condition at the end and then the read follows until the rx_done flag is set.

But the i2c module returns status_busy when I want to start the read with "i2c_master_read_packet_job". That is not surprising, because the module is busy due to the missing stop condition.

Now I don't have an idea how to get that to work? How can I solve that conflict?

 

Regards, Markus

Last Edited: Fri. Feb 12, 2021 - 05:12 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hello!

I'm trying to communicate SAML21 with chip LM3370 (which has 3 different registers) over I2C. I've tried the same as you:

"I tried to send the address of the register always as first data byte and the data itself as second byte, but it seems not to run, although the procedure should be OK." 

 

Also, ASF examples doesn´t  show how to specify the register addresses.

 

I was frustrated until I found this forum and I read you could solve it already.

 

Could you please share your I2C_send.h file? I couldn't open it.

 

TIA! 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

lauraximena wrote:
ASF examples doesn´t  show how to specify the register addresses.

That's because ASF (and, in fact, I2C itself) knows nothing about "register addresses" - these are entirely a thing defined by the particular slave chip.

 

As far as ASF (and, in fact, I2C itself) is concerned, it's all just data.

 

I2C Specification: https://www.nxp.com/docs/en/user-guide/UM10204.pdf

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Thu. Jul 22, 2021 - 09:04 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Right! 

 

Do you have any example of I2C protocol using SAM and slaves which have registers addresses?

 

I would appreciate it. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

'fraid not.

 

frown

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks, though.