Author Topic: I2C Atmel  (Read 16024 times)

0 Members and 1 Guest are viewing this topic.

Offline funkathustra

  • Regular Contributor
  • *
  • Posts: 150
  • Country: us
Re: I2C Atmel
« Reply #50 on: October 05, 2017, 05:13:58 pm »
Again, @ataradov is dead-on.

For inspecting return codes, I typically have an "error" variable that is reused; I can inspect it while debugging to see what the actual error codes are.

Code: [Select]
int8_t error;

error = someFunction1();
if(!error)
{
   return -1;
}

error = someFunction2();
if(!error)
{
   return -1;
}

// etc.


Just to add: I would never bring up a communication bus (including I2C) without a logic analyzer (or at least a scope).

The gold standard for USB-based ones is the Saleae Logic, but there are clones of the older Saleae gear, too (e.g. this one).


If you buy a clone, please consider using it with the open-source sigrok project, instead of the Saleae software. Sigrok have support for many of these Cypress FX2-based devices, and works similarly to Saleae.

If you can afford a Saleae, they are much better than their clones --- they have the ability to capture analog signals in addition to digital ones, which is useful when you're dealing with funny hardware / GPIO configurations.

I once had an I2C bus that appeared to be stuck at ground, but when I captured it with a Saleae, I saw the traffic was only reaching about 0.7V, and tracked it down to a bad chip that had shorted out (and turned into a diode!). If I didn't have an analog-capture logic analyzer, I would have assumed it was my I2C initialization routine.
 

Offline d-jokic

  • Contributor
  • Posts: 25
  • Country: us
Re: I2C Atmel
« Reply #51 on: October 05, 2017, 06:20:29 pm »
Hi,

I understand what @funkathustra are doing, my issue is that I don't know how to "view" a return in C. So how would I inspect your error variable. I know this is very simple to do, I just can't find it online (probably because it's so basic).

I will look into getting a logic analyzer. I know that the chip and sensor are fine, since they work with my old Arduino code. I'm using a MAX30105 sensor connected to an Arduino Zero, and I'm using atmel studio to write code to the SAMD21 chip via the EDBG  (Atmel® Embedded Debugger). If I resort back to the Arduino IDE, I am able to establish communication with the sensor, so I know that both the chip and sensor are functional .
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: I2C Atmel
« Reply #52 on: October 05, 2017, 06:25:13 pm »
I don't know how to "view" a return in C. So how would I inspect your error variable.
You are contradicting yourself here. In this code return value of a function is assigned to a variable, and you know how to inspect variables already.

In general, I would recommend to not use the debugger, and learn to do things like this in the code. One of the most common techniques is to set a pin high or low depending on a return value of a function.
Alex
 

Offline d-jokic

  • Contributor
  • Posts: 25
  • Country: us
Re: I2C Atmel
« Reply #53 on: October 05, 2017, 06:54:29 pm »
I was going to do setting a pin high/ low but my code for this is in another project, and combining them gives me errors regarding the MakeFile. I haven't had time to look into what these are quite yet. But I believe that your code has functions that I could use; I'm assuming I could do something like this, using the gpio.h and gpio.c files:

Code: [Select]
gpio_init();
gpio_configure(0, GPIO_CONF_OUTPUT); //configure PB0 as output --> index 0 = PB0 in declarations
gpio_write(0, 1);                                    //write 1 (HIGH) to index 0   

However, i did the following earlier:
Code: [Select]
        uint8_t error = 0;

if( i2c_init(100) != 100 ){
error = 1;
} else {
error = 2;
}

And then using a watch I reviewed the value of the error. Right now the watch says the value is 1; meaning that i2c_init is not returning freq = 100. I'm not sure how to interpret that.
 

Offline d-jokic

  • Contributor
  • Posts: 25
  • Country: us
Re: I2C Atmel
« Reply #54 on: October 05, 2017, 07:25:23 pm »
I also want to make sure I implemented your project correctly, though I feel as though it would throw an error if it wasn't. I downloaded mcu-starter-project-master from GitHub. I then added the i2c-master files to the project from the embedded file on your github. However, I didn't change anything in the make or linker folders. I'm not sure if I was supposed to. It doesn't throw an error, and Im not familiar with how or what these files do, so I wanted to check if I should change them.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: I2C Atmel
« Reply #55 on: October 05, 2017, 07:41:26 pm »
I'm not sure how to interpret that.
Very simple. Exact frequency you have requested is almost never going to be achievable. Especially 100 Hz, as I said earlier, there is just not enough bits in the divider to get a frequency this low. This is not a problem at all.

You need to monitor results of all other functions, that actually do the work.
Alex
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: I2C Atmel
« Reply #56 on: October 05, 2017, 07:43:26 pm »
I also want to make sure I implemented your project correctly, though I feel as though it would throw an error if it wasn't. I downloaded mcu-starter-project-master from GitHub. I then added the i2c-master files to the project from the embedded file on your github. However, I didn't change anything in the make or linker folders. I'm not sure if I was supposed to. It doesn't throw an error, and Im not familiar with how or what these files do, so I wanted to check if I should change them.
That's generally a correct way of doing things. But you actually need to understand what the code is doing, and what results are expected at each step. Then you will be a able to tell what is wrong.
Alex
 

Offline d-jokic

  • Contributor
  • Posts: 25
  • Country: us
Re: I2C Atmel
« Reply #57 on: October 05, 2017, 09:53:58 pm »
I've managed to get it working, however one thing that I've noticed is that when I changed the pins (tried to use pa22 and pa23 instead for i2c - I wasn't using UART at the time either, I know those pins are used for UART in Alex's code), it won't work. I changed the sercom number accordingly. I've also tried using your UART functions to view things over the terminal. The main.c within your GitHub does:
Code: [Select]
  uart_init(115200);
  uart_puts("\r\nHello, world!\r\n");
Is there something that needs to be added in order for the data to be seen on the terminal? Currently if I run you's main.c code for UART, nothing shows up on the terminal. Is there a terminal you recommend using rather than the one built into Atmel Studio? I've got the same baud rate on the terminal, and I've got it set up such that the com output is the terminal input.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: I2C Atmel
« Reply #58 on: October 05, 2017, 09:58:48 pm »
I don't understand what you have changed and what you expect to happen. Do you want to remap UART to some other pins? What pins?

I personally use TeraTerm and happy with it.
Alex
 

Offline d-jokic

  • Contributor
  • Posts: 25
  • Country: us
Re: I2C Atmel
« Reply #59 on: October 05, 2017, 10:20:00 pm »
Yes. So originally I was going to use PA22 and PA23, since those are the dedicated I2C pins on the Ardiuno and it would just be easier for me when it came to plugging in the sensor (since those pins are labeled sda and scl). Eventually, I will have multiple sensors connected to this MCU, and wanted to make sure I could implement this setup onto multiple pins. When I changed the i2c pins from PA08 and PA09 to PA22 and PA23, I commented out the UART functions since that is connected to PA22 and PA23 in your code. I also changed I2C_SERCOM and all the other sercom related declarations to the appropriate sercom (since pa22 and pa23 are connected to sercom3 and pa08 and pa09 are connected to sercom2). In this case, i2c didn't work, so I changed everything back to the original pa08 and pa09 configuration and it worked. I'm assuming I forgot to change something within the sercom declarations.

For now I've left the i2c connected on pa08 and pa09 and UART on pa22 and pa23, as in your code. However, I can't get UART to work.  I've got the sample code from your main.c to test out before trying to implement it into my project. It is a simple uart_init(baud) and uart_puts(Hello World). However, nothing shows up on my terminal in Atmel Studio. I've ensured that the baud rates are the same and that the output from the com port is the input into the terminal. I also tried it on the Arduino serial monitor (loaded the code into the arduino via Atmel Studio and then opened the Arduino Serial monitor) and once again get nothing. I was thinking that since pa22 and pa23 are i2c designated on the arduino, and since I'm using an arduino and not the naked atsamd21 chip, this could cause a problem. So i tried remapping uart to pa10 and pa11 (sercom0) which is the serial port on the arduino. However this didn't work either.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: I2C Atmel
« Reply #60 on: October 05, 2017, 10:34:01 pm »
Let's start simple. Download plain mcu-starter-projects/samd21 and try PA22/PA23 using TeraTerm. You need to get this configuration work first before you can move on with any changes.
Alex
 

Offline d-jokic

  • Contributor
  • Posts: 25
  • Country: us
Re: I2C Atmel
« Reply #61 on: October 05, 2017, 11:08:03 pm »
I tried what you suggested, and still get nothing. I don't actually connect anything to pa23 and pa22 though, right? This is why I think I should change it to pins pa10 and pa11 since those are routed for uart on the arduino, as far as i undertsand anayway.

I did try changing the pins to pa10 and pa11,  sercom to sercom0 and the pads to pads 2 and 3 on sercom0, and still got nothing on TeraTerm
Old code:
Code: [Select]
HAL_GPIO_PIN(UART_TX,  A, 22)
HAL_GPIO_PIN(UART_RX,  A, 23)

static void uart_init(uint32_t baud)
{
  uint64_t br = (uint64_t)65536 * (F_CPU - 16 * baud) / F_CPU;

  HAL_GPIO_UART_TX_out();
  HAL_GPIO_UART_TX_pmuxen(PORT_PMUX_PMUXE_C_Val);
  HAL_GPIO_UART_RX_in();
  HAL_GPIO_UART_RX_pmuxen(PORT_PMUX_PMUXE_C_Val);

  PM->APBCMASK.reg |= PM_APBCMASK_SERCOM3;

  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(SERCOM3_GCLK_ID_CORE) |
      GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0);

  SERCOM3->USART.CTRLA.reg =
      SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_MODE_USART_INT_CLK |
      SERCOM_USART_CTRLA_RXPO(1/*PAD1*/) | SERCOM_USART_CTRLA_TXPO(0/*PAD0*/);

  SERCOM3->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN |
      SERCOM_USART_CTRLB_CHSIZE(0/*8 bits*/);

  SERCOM3->USART.BAUD.reg = (uint16_t)br;

  SERCOM3->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
}

//-----------------------------------------------------------------------------
static void uart_putc(char c)
{
  while (!(SERCOM3->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_DRE));
  SERCOM3->USART.DATA.reg = c;
}

//-----------------------------------------------------------------------------
static void uart_puts(char *s)
{
  while (*s)
    uart_putc(*s++);
}


NEW CODE:
Code: [Select]
HAL_GPIO_PIN(UART_TX,  A, 10)
HAL_GPIO_PIN(UART_RX,  A, 11)


static void uart_init(uint32_t baud)
{
  uint64_t br = (uint64_t)65536 * (F_CPU - 16 * baud) / F_CPU;

  HAL_GPIO_UART_TX_out();
  HAL_GPIO_UART_TX_pmuxen(PORT_PMUX_PMUXE_C_Val);
  HAL_GPIO_UART_RX_in();
  HAL_GPIO_UART_RX_pmuxen(PORT_PMUX_PMUXE_C_Val);

  PM->APBCMASK.reg |= PM_APBCMASK_SERCOM0;

  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(SERCOM0_GCLK_ID_CORE) |
      GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0);

  SERCOM0->USART.CTRLA.reg =
      SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_MODE_USART_INT_CLK |
      SERCOM_USART_CTRLA_RXPO(3/*PAD1*/) | SERCOM_USART_CTRLA_TXPO(2/*PAD0*/);

  SERCOM0->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN |
      SERCOM_USART_CTRLB_CHSIZE(0/*8 bits*/);

  SERCOM0->USART.BAUD.reg = (uint16_t)br;

  SERCOM0->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
}

//-----------------------------------------------------------------------------
static void uart_putc(char c)
{
  while (!(SERCOM0->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_DRE));
  SERCOM0->USART.DATA.reg = c;
}

//-----------------------------------------------------------------------------
static void uart_puts(char *s)
{
  while (*s)
    uart_putc(*s++);
}


If the original code works for you over teraterm, could it be something to do with using the Arduino instead of the mcu alone?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: I2C Atmel
« Reply #62 on: October 05, 2017, 11:12:14 pm »
I tried what you suggested, and still get nothing. I don't actually connect anything to pa23 and pa22 though, right?
No, you connect USB-to-Serial adapter to them.

This is why I think I should change it to pins pa10 and pa11 since those are routed for uart on the arduino, as far as i undertsand anayway.
What Arduino are we talking about? Arduino Zero has EDBG CDC port connected to PB22/PB23.

Alex
 

Offline d-jokic

  • Contributor
  • Posts: 25
  • Country: us
Re: I2C Atmel
« Reply #63 on: October 05, 2017, 11:18:46 pm »
I don't have an adapter on hand, which is why I was hoping to make use of the Arduino's built in usb - serial connection. I thought that connecting to the RX and TX pins (pa11 and pa10) would accomplish this, since those are the serial RX and TX pins. Should it be to the edbg RX and TX, pb22 and pb23?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: I2C Atmel
« Reply #64 on: October 05, 2017, 11:21:09 pm »
Connecting PA11 and PA10 where? Can you actually describe what hardware you have on hand and how it is connected?
Alex
 

Offline d-jokic

  • Contributor
  • Posts: 25
  • Country: us
Re: I2C Atmel
« Reply #65 on: October 05, 2017, 11:28:21 pm »
Sure. I just have the Arduino Zero connected to the computer via usb-micro to usb cable. When I use the Arduino IDE this is sufficient, but I wouldn't be surprised if there more to it in this case.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: I2C Atmel
« Reply #66 on: October 05, 2017, 11:41:42 pm »
In that case rewrite the code to use PB22/PB23. PA10/PA11 are just spare pins.
Alex
 

Offline d-jokic

  • Contributor
  • Posts: 25
  • Country: us
Re: I2C Atmel
« Reply #67 on: October 06, 2017, 12:08:54 am »
Gave that a try too; still nothing. Changed sercom to sercom5 and pads accordingly. I'm looking through the code right now to see if I forgot anything. I checked and the program is able to complete each function (uart_init and uart_puts) however nothing is coming up on the TeraTerm. Maybe a board issue? My issue with using another board is that Atmel Studio requires a firmware update of the edbg. The update makes the Arduino unusable with the Arduino IDE. But if there's no other possible issues, then I can give that a try too; I have a spare Arduino somewhere.
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: I2C Atmel
« Reply #68 on: October 06, 2017, 12:15:18 am »
Ok, post your configuration code for  PB22/PB23.
Alex
 

Offline d-jokic

  • Contributor
  • Posts: 25
  • Country: us
Re: I2C Atmel
« Reply #69 on: October 06, 2017, 12:22:27 am »
I've attached the file as well:

Code: [Select]
/*
//-----------------------------------------------------------------------------
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "samd21.h"
#include "hal_gpio.h"

//-----------------------------------------------------------------------------
#define PERIOD_FAST     100
#define PERIOD_SLOW     500

HAL_GPIO_PIN(UART_TX,  B, 22)
HAL_GPIO_PIN(UART_RX,  B, 23)

//-----------------------------------------------------------------------------
static void timer_set_period(uint16_t i)
{
  TC3->COUNT16.CC[0].reg = (F_CPU / 1000ul / 256) * i;
  TC3->COUNT16.COUNT.reg = 0;
}

//-----------------------------------------------------------------------------
void irq_handler_tc3(void)
{
  if (TC3->COUNT16.INTFLAG.reg & TC_INTFLAG_MC(1))
  {
    //HAL_GPIO_LED_toggle();
    TC3->COUNT16.INTFLAG.reg = TC_INTFLAG_MC(1);
  }
}

//-----------------------------------------------------------------------------
static void timer_init(void)
{
  PM->APBCMASK.reg |= PM_APBCMASK_TC3;

  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(TC3_GCLK_ID) |
      GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0);

  TC3->COUNT16.CTRLA.reg = TC_CTRLA_MODE_COUNT16 | TC_CTRLA_WAVEGEN_MFRQ |
      TC_CTRLA_PRESCALER_DIV256 | TC_CTRLA_PRESCSYNC_RESYNC;

  TC3->COUNT16.COUNT.reg = 0;

  timer_set_period(PERIOD_SLOW);

  TC3->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE;

  TC3->COUNT16.INTENSET.reg = TC_INTENSET_MC(1);
  NVIC_EnableIRQ(TC3_IRQn);
}

//-----------------------------------------------------------------------------
static void uart_init(uint32_t baud)
{
  uint64_t br = (uint64_t)65536 * (F_CPU - 16 * baud) / F_CPU;

  HAL_GPIO_UART_TX_out();
  HAL_GPIO_UART_TX_pmuxen(PORT_PMUX_PMUXE_C_Val);
  HAL_GPIO_UART_RX_in();
  HAL_GPIO_UART_RX_pmuxen(PORT_PMUX_PMUXE_C_Val);

  PM->APBCMASK.reg |= PM_APBCMASK_SERCOM5;

  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(SERCOM5_GCLK_ID_CORE) |
      GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(0);

  SERCOM5->USART.CTRLA.reg =
      SERCOM_USART_CTRLA_DORD | SERCOM_USART_CTRLA_MODE_USART_INT_CLK |
      SERCOM_USART_CTRLA_RXPO(3/*PAD1*/) | SERCOM_USART_CTRLA_TXPO(2/*PAD0*/);

  SERCOM5->USART.CTRLB.reg = SERCOM_USART_CTRLB_RXEN | SERCOM_USART_CTRLB_TXEN |
      SERCOM_USART_CTRLB_CHSIZE(0/*8 bits*/);

  SERCOM5->USART.BAUD.reg = (uint16_t)br;

  SERCOM5->USART.CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE;
}

//-----------------------------------------------------------------------------
static void uart_putc(char c)
{
  while (!(SERCOM5->USART.INTFLAG.reg & SERCOM_USART_INTFLAG_DRE));
  SERCOM5->USART.DATA.reg = c;
}

//-----------------------------------------------------------------------------
static void uart_puts(char *s)
{
  while (*s)
    uart_putc(*s++);
}

//-----------------------------------------------------------------------------
static void sys_init(void)
{
  // Switch to 8MHz clock (disable prescaler)
  SYSCTRL->OSC8M.bit.PRESC = 0;

  // Enable interrupts
  asm volatile ("cpsie i");
}

//-----------------------------------------------------------------------------
int main(void)
{
  uint32_t cnt = 0;
  bool fast = false;

  sys_init();
  timer_init();

  uart_init(9600);

  uart_puts("\r\nHello, world!\r\n");

  while (1)
  {
  }

  return 0;
}

 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: I2C Atmel
« Reply #70 on: October 06, 2017, 01:31:54 am »
You have selected PMUX C, while SERCOM5 is on PMUX D.

Your TXPO is also incorrect, it should be 1. And always update comments to match the setting. Right now you are doing a great disservice to someone reading your code.

I'm also not sure about setting 9600 as a baudrate. I'd stick with 115200 for now.
Alex
 

Offline funkathustra

  • Regular Contributor
  • *
  • Posts: 150
  • Country: us
Re: I2C Atmel
« Reply #71 on: October 06, 2017, 06:17:36 am »
I understand what @funkathustra are doing, my issue is that I don't know how to "view" a return in C. So how would I inspect your error variable. I know this is very simple to do, I just can't find it online (probably because it's so basic).

Do you understand, though?

Code: [Select]
uint8_t error = someFunction();
if(error) ....
You realize that "error" is an 8-bit unsigned variable that holds the "return code" right? You can set a break point on that line, and the moment you step over it (to the next line), the "error" variable will contain the result of someFunction() executing. You said you're not familiar with C — if you come from a high-level language like C#/Java/etc, you're probably thinking of exceptions or something like that; C has no exceptions.

The only thing a function can return is a return value, and you can read this value and assign it to a variable in your source code, as I do above. Once it's assigned to a variable, it will occupy memory, and your debugger can inspect it.

Having said all that....

Can we just go big-picture for a second?

Don't take this the wrong way, but you don't seem to really have any idea what you're doing or why you're doing it. You don't seem to be interested in these individual lines of code and what they do (since all you're doing is copying-pasting stuff around into a big mess). I want to pause and say there's absolutely nothing wrong with that, by the way. I'm just stating an observation.

Microcontrollers have registers. Lots of registers. Registers for the SERCOM modules, for the timers, for the GPIO, and for everything else on the chip. You manipulate the bits in the registers to do what you want to do.

You can keep the SAM D21 datasheet up on your screen, and use the debugger to inspect the peripheral registers to ensure that the correct bits are getting set and cleared for the operations you're trying to perform, as you walk through your code. But you need to know what to expect to see, at the register level. When you mux the proper pins to the UART, what are the register values you expect to see? Does it match what your debugger says the actual bits are?

At a very low level, this is how professional embedded developers like us can write and debug this sort of code.


Since you seem more interested in results, can I recommend you just use Atmel START? It's an online code-gen tool that will create all your initialization code for you, and provide high-level functions that you can use to get stuff done. It has a pin-mux tool that will let you assign UARTs or I2C pins where you want them, as well as initialize them with proper baud rate settings. You'll also get nice, high-level functions for interacting with them.

I do a ton of consulting work for start-ups and smaller companies, and everyone uses these tools all the time for "basic plumbing" of an application; just to get something up and running to show the boss. Sure, @ataradov will mention that some of these libraries of bugs in them, and some of them are slow — all true. But they *generally* work well, and they *generally* let you get away from the nitty-gritty details of your chip, which most people honestly aren't interested in anyway.

I've been in discussions with @ataradov on these forums about this stuff before, and while we agree on a lot of embedded stuff, we have very different perspectives on these things — he's very much opposed to peripheral libraries and code configurators and I think debuggers as well.

I have to disagree with him on those points. It totally depends on the user. Personally, I have no problem working at the register level of modern ARM microcontrollers, but for hobbyists and new users who aren't $200-an-hour embedded engineers, that might not be feasible. That's why I highly recommend code configurator tools — especially for basic projects and when working on parts that need a lot of TLC to get up and running (like an ARM microcontroller or any modern 8-bit or 16-bit device with clock gating, pin muxing, etc).

And I think his recommendation to use pin-toggling instead of a debugger is fucking ridiculous. Debuggers let you step through your code entirely while you're observing all the peripheral registers of a CPU. It's great for debugging, but it's also great for learning, since you can see exactly what each function is doing to the bits in all the registers.

I think people like @ataradov have a much higher tolerance for dealing with a steep learning-curve when using a new microcontroller than I have, so they're fine with sitting around wiggling pins, seeing if a bit got set or not. No offense to @ataradov, but it also feels like kind of an old-timer "well, this is how I learned it, and it was good enough for me, so it's good enough for you" sort of attitude.

I have no patience for that, so I'm always using a debugger when bringing up a chip and getting peripherals working. Once you know a microcontroller (and a set of peripheral libraries) really well, then sure, you don't need a debugger constantly attached to your system (but since modern MCUs are programmed through the same connection, there's really no difference).

Anyway, please, continue using it, as it's a great tool — at all levels of development.

« Last Edit: October 06, 2017, 06:21:21 am by funkathustra »
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: I2C Atmel
« Reply #72 on: October 06, 2017, 06:27:19 am »
No offense to @ataradov, but it also feels like kind of an old-timer "well, this is how I learned it, and it was good enough for me, so it's good enough for you" sort of attitude.
None taken, and I'm not that old :). I do use debugger when I believe it is warranted (pretty rare). I'm in the process of making my own debugger actually.

But this is not because of how I used to do that, it is because I'm very aware of side effects debuggers cause. Even the most modern and non-intrusive debuggers have a lot of side effects.

You would not believe how often I get a question like "I try to debug my program, but it breaks even more when I use a debugger". And the solution is always to close the "I/O View" window. The debugger reads all those clear-on-read registers, messing up execution of the main program.

Debuggers are very powerful tools, but they can be dangerous, especially for beginners.

EDIT: Another good one - Atmel Studio lets you put a lot of break points, more than you have actual hardware comparators. It is doing this by replacing original instruction with a breakpoints instruction and overwriting it in the flash. This has a ton of nasty side effects. If you are aware of them - that's great, but it is a huge "trap for young players" otherwise.

That's exactly why I'm making my own debugger. I need to know what debugger is doing at any point in time, otherwise I don't feel in control, and I hate that.
« Last Edit: October 06, 2017, 06:33:31 am by ataradov »
Alex
 

Offline funkathustra

  • Regular Contributor
  • *
  • Posts: 150
  • Country: us
Re: I2C Atmel
« Reply #73 on: October 06, 2017, 06:52:37 am »
That's exactly why I'm making my own debugger. I need to know what debugger is doing at any point in time, otherwise I don't feel in control, and I hate that.

Neat! Do you have info about this project anywhere on the forums?
 

Online ataradov

  • Super Contributor
  • ***
  • Posts: 11269
  • Country: us
    • Personal site
Re: I2C Atmel
« Reply #74 on: October 06, 2017, 06:55:28 am »
Neat! Do you have info about this project anywhere on the forums?
Nope, it is pretty low priority. It is probably behind 2-3 other projects on the list.

It is basically an extension of the CMSIS-DAP programmer to basic and plain CMSIS-DAP debugger. I have test bits and pieces, and I know that I can do the things debuggers supposed to do (BPs, single stepping, reading registers, memory, etc), but I need time to assemble all this into a coherent thing with UI.
« Last Edit: October 06, 2017, 06:58:20 am by ataradov »
Alex
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf