Better define checks.
M platform_samd_clocks.c +4 -4
@@ 59,7 59,7 @@ CTL_STATUS_t sercom_init_clocks(uint8_t 
       slow_clk_id = SERCOM3_GCLK_ID_SLOW;
       break;
 #endif
-#if defined(_SAMD21_) || defined(_SAMD20_)
+#if defined(SERCOM4_GCLK_ID_CORE)
     case 4:
       PM->APBCMASK.reg |= PM_APBCMASK_SERCOM4;
 

          
@@ 67,7 67,7 @@ CTL_STATUS_t sercom_init_clocks(uint8_t 
       slow_clk_id = SERCOM4_GCLK_ID_SLOW;
       break;
 #endif
-#if defined(_SAMD21_) || defined(_SAMD20_)
+#if defined(SERCOM5_GCLK_ID_CORE)
     case 5:
       PM->APBCMASK.reg |= PM_APBCMASK_SERCOM5;
 

          
@@ 137,7 137,7 @@ CTL_STATUS_t sercom_disable_clock(uint8_
       slow_clk_id = SERCOM3_GCLK_ID_SLOW;
       break;
 #endif
-#if defined(_SAMD21_) || defined(_SAMD20_)
+#if defined(SERCOM4_GCLK_ID_CORE)
     case 4:
       apb_mask = PM_APBCMASK_SERCOM4;
 

          
@@ 145,7 145,7 @@ CTL_STATUS_t sercom_disable_clock(uint8_
       slow_clk_id = SERCOM4_GCLK_ID_SLOW;
       break;
 #endif
-#if defined(_SAMD21_) || defined(_SAMD20_)
+#if defined(SERCOM5_GCLK_ID_CORE)
     case 5:
       apb_mask = PM_APBCMASK_SERCOM5;
 

          
M platform_samd_i2c.c +33 -6
@@ 246,7 246,11 @@ private_i2c_init_master(uint8_t sercom_n
   I2C_SYNCBUSY_SWRST(dev);
 
   if (speed >= 3400000) {
-    dev->I2CM.CTRLA.reg = SERCOM_I2CM_CTRLA_MODE_I2C_MASTER | SERCOM_I2CM_CTRLA_SDAHOLD(0x2) | SERCOM_I2CM_CTRLA_SCLSM;
+    dev->I2CM.CTRLA.reg = SERCOM_I2CM_CTRLA_MODE_I2C_MASTER | SERCOM_I2CM_CTRLA_SDAHOLD(0x2)
+#if REV_SERCOM >= 0x200
+    | SERCOM_I2CM_CTRLA_SCLSM
+#endif
+    ;
   } else {
     dev->I2CM.CTRLA.reg = SERCOM_I2CM_CTRLA_MODE_I2C_MASTER;
   }

          
@@ 256,7 260,11 @@ private_i2c_init_master(uint8_t sercom_n
   private_samd_set_speed(sercom_no, speed);
 
   sercom_enable_interrupt(sercom_no);
-  dev->I2CM.INTENSET.reg = SERCOM_I2CM_INTFLAG_MB|SERCOM_I2CM_INTFLAG_SB|SERCOM_I2CM_INTFLAG_ERROR;
+  dev->I2CM.INTENSET.reg = SERCOM_I2CM_INTFLAG_MB|SERCOM_I2CM_INTFLAG_SB
+#if REV_SERCOM >= 0x200
+  |SERCOM_I2CM_INTFLAG_ERROR
+#endif
+  ;
 
   dev->I2CM.CTRLA.bit.ENABLE = 1;
   I2C_SYNCBUSY(dev);

          
@@ 337,6 345,7 @@ samd_i2c_transaction(CTL_I2C_BUS_t *supe
   unsigned wait_status;
   size_t total_len;
   uint32_t counter = 0;
+  CTL_TIME_t wait_timeout = 100;
 
   // Save transaction.
   self->request = *request;

          
@@ 355,16 364,26 @@ samd_i2c_transaction(CTL_I2C_BUS_t *supe
 
   ctl_events_set_clear(&self->events, 0, TRANSFER_DONE_EVENT|ERROR_EVENT);
 
-  dev->I2CM.INTENSET.reg = SERCOM_I2CM_INTFLAG_MB|SERCOM_I2CM_INTFLAG_SB|SERCOM_I2CM_INTFLAG_ERROR;
+  dev->I2CM.INTENSET.reg = SERCOM_I2CM_INTFLAG_MB|SERCOM_I2CM_INTFLAG_SB
+#if REV_SERCOM >= 0x200
+  |SERCOM_I2CM_INTFLAG_ERROR
+#endif
+  ;
   if (request->tx) {
     private_send_start(self->sercom, self->request.address, true, super->__speed >= 3400000);
   } else {
     private_send_start(self->sercom, self->request.address, false, super->__speed >= 3400000);
   }
 
+  wait_timeout = 2 + (self->request.rxlen + self->request.txlen) * 10;
+  if (wait_timeout < 10)
+    wait_timeout = 10;
+  if (wait_timeout > 10000)
+    wait_timeout = 10000;
+
   wait_status = ctl_events_wait(CTL_EVENT_WAIT_ANY_EVENTS_WITH_AUTO_CLEAR,
     &self->events, TRANSFER_DONE_EVENT|ERROR_EVENT,
-    CTL_TIMEOUT_DELAY, 10000);
+    CTL_TIMEOUT_DELAY, wait_timeout);
 
   if (wait_status == 0) { // timeout
     private_send_stop(self->sercom);

          
@@ 400,7 419,11 @@ static void private_send_start(uint8_t s
   // reply ack
   dev->I2CM.CTRLB.reg &= ~SERCOM_I2CM_CTRLB_ACKACT;
   if (high_speed) {
-    dev->I2CM.ADDR.reg = addr | SERCOM_I2CM_ADDR_HS;
+    dev->I2CM.ADDR.reg = addr
+#ifdef SERCOM_I2CM_ADDR_HS
+    | SERCOM_I2CM_ADDR_HS
+#endif
+    ;
   } else {
     dev->I2CM.ADDR.reg = addr;
   }

          
@@ 435,7 458,11 @@ i2c_sercom_handler(D21_I2C_BUS_t *self)
   ctl_enter_isr();
 
   dev = I2CS[self->sercom].dev;
+#ifdef SERCOM_I2CM_ADDR_HS
   sclsm = dev->I2CM.CTRLA.bit.SCLSM != 0;
+#else
+  sclsm = false;
+#endif
 
   int_flag = dev->I2CM.INTFLAG.reg;
   bus_status = dev->I2CM.STATUS.reg;

          
@@ 458,7 485,7 @@ i2c_sercom_handler(D21_I2C_BUS_t *self)
            (bus_status & SERCOM_I2CM_STATUS_RXNACK)) {
     // nack, no device in the specified address?
     private_send_stop(self->sercom);
-    if (self->request.rxlen > 0) {
+    if (self->request.rxlen > 0 || self->request.txlen > 0) {
       ctl_events_set_clear(&self->events, ERROR_EVENT, 0);
     } else {
       ctl_events_set_clear(&self->events, TRANSFER_DONE_EVENT, 0);

          
M platform_samd_sercom.c +8 -0
@@ 71,15 71,19 @@ CTL_STATUS_t sercom_enable_interrupt(uin
       ctl_set_priority(SERCOM3_IRQn, 1);
       ctl_unmask_isr(SERCOM3_IRQn);
       break;
+#ifdef SERCOM4_GCLK_ID_CORE
     case 4:
       ctl_set_priority(SERCOM4_IRQn, 1);
       ctl_unmask_isr(SERCOM4_IRQn);
       break;
+#endif
+#ifdef SERCOM5_GCLK_ID_CORE
     case 5:
       ctl_set_priority(SERCOM5_IRQn, 1);
       ctl_unmask_isr(SERCOM5_IRQn);
       break;
 #endif
+#endif
     default:
       return CTL_PARAMETER_ERROR;
   }

          
@@ 104,12 108,16 @@ CTL_STATUS_t sercom_disable_interrupt(ui
       ctl_mask_isr(SERCOM3_IRQn);
       break;
     case 4:
+#ifdef SERCOM4_GCLK_ID_CORE
       ctl_mask_isr(SERCOM4_IRQn);
       break;
+#endif
+#ifdef SERCOM5_GCLK_ID_CORE
     case 5:
       ctl_mask_isr(SERCOM5_IRQn);
       break;
 #endif
+#endif
     default:
       return CTL_PARAMETER_ERROR;
   }

          
M platform_samd_tc.c +3 -3
@@ 155,7 155,7 @@ private_samd_tc_init_16b(uint8_t timer_n
       dev = TC2;
       irq_n = TC2_IRQn;
       break;
-#elif defined(_SAMD21_) || defined(_SAMD20_)
+#elif defined(GCLK_CLKCTRL_ID_TCC2_TC3)
     case 3:
       PM->APBCMASK.reg |= PM_APBCMASK_TC3;
       clock_ctrl_id = GCLK_CLKCTRL_ID_TCC2_TC3;

          
@@ 288,7 288,7 @@ int samd_tc_init_pwm_with_prescaler_8b(u
       clock_ctrl_id = GCLK_CLKCTRL_ID_TC1_TC2;
       dev = TC2;
       break;
-#elif defined(_SAMD21_) || defined(_SAMD20_)
+#elif defined(GCLK_CLKCTRL_ID_TCC2_TC3)
     case 3:
       PM->APBCMASK.reg |= PM_APBCMASK_TC3;
       clock_ctrl_id = GCLK_CLKCTRL_ID_TCC2_TC3;

          
@@ 443,7 443,7 @@ int samd_tc_init_16b_ms_tick(uint8_t tim
       dev = TC2;
       irq_n = TC2_IRQn;
       break;
-#elif defined(_SAMD21_) || defined(_SAMD20_)
+#elif defined(GCLK_CLKCTRL_ID_TCC2_TC3)
     case 3:
       PM->APBCMASK.reg |= PM_APBCMASK_TC3;
       clock_ctrl_id = GCLK_CLKCTRL_ID_TCC2_TC3;

          
M platform_samd_uart.c +4 -0
@@ 403,6 403,7 @@ static PLATFORM_SAMD_UART_t samd_uarts[]
     .core.ready = samd_uart_ready,
     .core.reconfigure = samd_uart_reconfigure
   },
+#ifdef SERCOM4
   {
     .dev = SERCOM4,
     .uart_no = 4,

          
@@ 415,6 416,8 @@ static PLATFORM_SAMD_UART_t samd_uarts[]
     .core.ready = samd_uart_ready,
     .core.reconfigure = samd_uart_reconfigure
   },
+#endif
+#ifdef SERCOM5
   {
     .dev = SERCOM5,
     .uart_no = 5,

          
@@ 428,6 431,7 @@ static PLATFORM_SAMD_UART_t samd_uarts[]
     .core.reconfigure = samd_uart_reconfigure
   }
 #endif
+#endif
 };
 
 CTL_UART_t*

          
M samd21-peripherals.hzp +2 -0
@@ 51,6 51,7 @@ 
       <file file_name="platform_samd_tickless_idle.c" />
       <file file_name="platform_samd_uart.c" />
       <file file_name="platform_samd_wdt.c" />
+      <file file_name="platform_samd_dma.c" />
     </folder>
     <folder Name="include">
       <file file_name="numeric_utils.h" />

          
@@ 70,6 71,7 @@ 
       <file file_name="platform_samd_tickless_idle.h" />
       <file file_name="platform_samd_uart.h" />
       <file file_name="platform_samd_wdt.h" />
+      <file file_name="platform_samd_dma.h" />
     </folder>
   </project>
   <configuration Name="THUMB Debug" inherited_configurations="THUMB;Debug" />

          
M samd21-peripherals.hzs +3 -2
@@ 37,8 37,9 @@ 
  </Watch4>
  <Files>
   <SessionOpenFile windowGroup="DockEditLeft" x="0" y="58" useTextEdit="1" useBinaryEdit="0" left="0" path="platform_samd_adc.c" debugPath="platform_samd_adc.c" selected="0" top="39" codecName="Default"/>
-  <SessionOpenFile windowGroup="DockEditLeft" x="25" y="20" useTextEdit="1" useBinaryEdit="0" left="0" path="C:/Program Files/Rowley Associates Limited/CrossWorks for ARM 4.0/include/ctl_api.h" debugPath="C:/Program Files/Rowley Associates Limited/CrossWorks for ARM 4.0/include/ctl_api.h" selected="0" top="0" codecName="Default"/>
-  <SessionOpenFile windowGroup="DockEditLeft" x="73" y="13" useTextEdit="1" useBinaryEdit="0" left="0" path="platform_samd_clocks.c" debugPath="platform_samd_clocks.c" selected="1" top="0" codecName="Default"/>
+  <SessionOpenFile windowGroup="DockEditLeft" x="0" y="20" useTextEdit="1" useBinaryEdit="0" left="0" path="C:/Program Files/Rowley Associates Limited/CrossWorks for ARM 4.0/include/ctl_api.h" debugPath="C:/Program Files/Rowley Associates Limited/CrossWorks for ARM 4.0/include/ctl_api.h" selected="0" top="0" codecName="Default"/>
+  <SessionOpenFile windowGroup="DockEditLeft" x="0" y="13" useTextEdit="1" useBinaryEdit="0" left="0" path="platform_samd_clocks.c" debugPath="platform_samd_clocks.c" selected="0" top="0" codecName="Default"/>
+  <SessionOpenFile windowGroup="DockEditLeft" x="21" y="78" useTextEdit="1" useBinaryEdit="0" left="0" path="platform_samd_i2c.c" debugPath="platform_samd_i2c.c" selected="1" top="60" codecName="Default"/>
  </Files>
  <ARMCrossStudioWindow activeProject="samd21-peripherals" fileDialogDefaultFilter="" autoConnectTarget="CrossConnect for ARM" buildConfiguration="THUMB Debug" debugSearchFileMap="" fileDialogInitialDirectory="C:/Users/tkoskine/Documents/CrossWorks Projects/samd2x-peripheral-lib" debugSearchPath="" autoConnectCapabilities="388479"/>
 </session>