samd: Add support for L21 & L22 (PR #345)

This commit is contained in:
dpslwk 2018-05-06 15:10:16 +01:00 committed by UweBonnes
parent 04d9749f25
commit 67f9d26644
1 changed files with 126 additions and 13 deletions

View File

@ -25,6 +25,7 @@
* * SAMD20E17A (rev C)
* * SAMD20J18A (rev B)
* * SAMD21J18A (rev B)
* * SAML21J17B (rev B)
* *
*/
/* Refer to the SAM D20 Datasheet:
@ -129,14 +130,16 @@ const struct command_s samd_cmd_list[] = {
#define SAMD_STATUSB_PROT (1 << 16)
/* Device Identification Register (DID) */
#define SAMD_DID_MASK 0xFFBC0000
#define SAMD_DID_MASK 0xFF3C0000
#define SAMD_DID_CONST_VALUE 0x10000000
#define SAMD_DID_DEVSEL_MASK 0x0F
#define SAMD_DID_DEVSEL_MASK 0xFF
#define SAMD_DID_DEVSEL_POS 0
#define SAMD_DID_REVISION_MASK 0x0F
#define SAMD_DID_REVISION_POS 8
#define SAMD_DID_SERIES_MASK 0x03
#define SAMD_DID_SERIES_MASK 0x1F
#define SAMD_DID_SERIES_POS 16
#define SAMD_DID_FAMILY_MASK 0x1F
#define SAMD_DID_FAMILY_POS 23
/* Peripheral ID */
#define SAMD_PID_MASK 0x00F7FFFF
@ -145,6 +148,79 @@ const struct command_s samd_cmd_list[] = {
/* Component ID */
#define SAMD_CID_VALUE 0xB105100D
/* Family parts */
struct samd_part {
uint8_t devsel;
char pin;
uint8_t mem;
uint8_t variant;
};
static const struct samd_part samd_d21_parts[] = {
{0x00, 'J', 18, 'A'}, /* SAMD21J18A */
{0x01, 'J', 17, 'A'}, /* SAMD21J17A */
{0x02, 'J', 16, 'A'}, /* SAMD21J16A */
{0x03, 'J', 15, 'A'}, /* SAMD21J15A */
{0x05, 'G', 18, 'A'}, /* SAMD21G18A */
{0x06, 'G', 17, 'A'}, /* SAMD21G17A */
{0x07, 'G', 16, 'A'}, /* SAMD21G16A */
{0x08, 'G', 15, 'A'}, /* SAMD21G15A */
{0x0A, 'E', 18, 'A'}, /* SAMD21E18A */
{0x0B, 'E', 17, 'A'}, /* SAMD21E17A */
{0x0C, 'E', 16, 'A'}, /* SAMD21E16A */
{0x0D, 'E', 15, 'A'}, /* SAMD21E15A */
{0x0F, 'G', 18, 'A'}, /* SAMD21G18A (WLCSP) */
{0x10, 'G', 17, 'A'}, /* SAMD21G17A (WLCSP) */
{0x20, 'J', 16, 'B'}, /* SAMD21J16B */
{0x21, 'J', 15, 'B'}, /* SAMD21J15B */
{0x23, 'G', 16, 'B'}, /* SAMD21G16B */
{0x24, 'G', 15, 'B'}, /* SAMD21G15B */
{0x26, 'E', 16, 'B'}, /* SAMD21E16B */
{0x27, 'E', 15, 'B'}, /* SAMD21E15B */
{0x55, 'E', 16, 'B'}, /* SAMD21E16B (WLCSP) */
{0x56, 'E', 15, 'B'}, /* SAMD21E15B (WLCSP) */
{0x62, 'E', 16, 'C'}, /* SAMD21E16C (WLCSP) */
{0x63, 'E', 15, 'C'}, /* SAMD21E15C (WLCSP) */
{0xFF, 0, 0, 0}
};
static const struct samd_part samd_l21_parts[] = {
{0x00, 'J', 18, 'A'}, /* SAML21J18A */
{0x01, 'J', 17, 'A'}, /* SAML21J17A */
{0x02, 'J', 16, 'A'}, /* SAML21J16A */
{0x05, 'G', 18, 'A'}, /* SAML21G18A */
{0x06, 'G', 17, 'A'}, /* SAML21G17A */
{0x07, 'G', 16, 'A'}, /* SAML21G16A */
{0x0A, 'E', 18, 'A'}, /* SAML21E18A */
{0x0B, 'E', 17, 'A'}, /* SAML21E17A */
{0x0C, 'E', 16, 'A'}, /* SAML21E16A */
{0x0D, 'E', 15, 'A'}, /* SAML21E15A */
{0x0F, 'J', 18, 'B'}, /* SAML21J18B */
{0x10, 'J', 17, 'B'}, /* SAML21J17B */
{0x11, 'J', 16, 'B'}, /* SAML21J16B */
{0x14, 'G', 18, 'B'}, /* SAML21G18B */
{0x15, 'G', 17, 'B'}, /* SAML21G17B */
{0x16, 'G', 16, 'B'}, /* SAML21G16B */
{0x19, 'E', 18, 'B'}, /* SAML21E18B */
{0x1A, 'E', 17, 'B'}, /* SAML21E17B */
{0x1B, 'E', 16, 'B'}, /* SAML21E16B */
{0x1C, 'E', 15, 'B'}, /* SAML21E15B */
{0xFF, 0, 0, 0}
};
static const struct samd_part samd_l22_parts[] = {
{0x00, 'N', 18, 'A'}, /* SAML22N18 */
{0x01, 'N', 17, 'A'}, /* SAML22N17 */
{0x02, 'N', 16, 'A'}, /* SAML22N16 */
{0x05, 'J', 18, 'A'}, /* SAML22J18 */
{0x06, 'J', 17, 'A'}, /* SAML22J17 */
{0x07, 'J', 16, 'A'}, /* SAML22J16 */
{0x0A, 'G', 18, 'A'}, /* SAML22G18 */
{0x0B, 'G', 17, 'A'}, /* SAML22G17 */
{0x0C, 'G', 16, 'A'}, /* SAML22G16 */
{0xFF, 0, 0, 0}
};
/**
* Reads the SAM D20 Peripheral ID
*/
@ -293,17 +369,23 @@ static bool samd_protected_attach(target *t)
* describing the SAM D device.
*/
struct samd_descr {
char family;
uint8_t series;
char revision;
char pin;
uint8_t mem;
char variant;
char package[3];
};
struct samd_descr samd_parse_device_id(uint32_t did)
{
struct samd_descr samd;
uint8_t i = 0;
const struct samd_part *parts = samd_d21_parts;
memset(samd.package, 0, 3);
uint8_t family = (did >> SAMD_DID_FAMILY_POS)
& SAMD_DID_FAMILY_MASK;
uint8_t series = (did >> SAMD_DID_SERIES_POS)
& SAMD_DID_SERIES_MASK;
uint8_t revision = (did >> SAMD_DID_REVISION_POS)
@ -311,11 +393,24 @@ struct samd_descr samd_parse_device_id(uint32_t did)
uint8_t devsel = (did >> SAMD_DID_DEVSEL_POS)
& SAMD_DID_DEVSEL_MASK;
/* Family */
switch (family) {
case 0: samd.family = 'D'; break;
case 1: samd.family = 'L'; parts = samd_l21_parts; break;
case 2: samd.family = 'C'; break;
}
/* Series */
switch (series) {
case 0: samd.series = 20; break;
case 1: samd.series = 21; break;
case 2: samd.series = 10; break;
case 2:
if (family == 1) {
samd.series = 22;
parts = samd_l22_parts;
} else {
samd.series = 10;
}
break;
case 3: samd.series = 11; break;
}
/* Revision */
@ -323,7 +418,6 @@ struct samd_descr samd_parse_device_id(uint32_t did)
switch (samd.series) {
case 20: /* SAM D20 */
case 21: /* SAM D21 */
switch (devsel / 5) {
case 0: samd.pin = 'J'; break;
case 1: samd.pin = 'G'; break;
@ -331,6 +425,20 @@ struct samd_descr samd_parse_device_id(uint32_t did)
default: samd.pin = 'u'; break;
}
samd.mem = 18 - (devsel % 5);
samd.variant = 'A';
break;
case 21: /* SAM D21/L21 */
case 22: /* SAM L22 */
i = 0;
while (parts[i].devsel != 0xFF) {
if (parts[i].devsel == devsel) {
samd.pin = parts[i].pin;
samd.mem = parts[i].mem;
samd.variant = parts[i].variant;
break;
}
i++;
}
break;
case 10: /* SAM D10 */
case 11: /* SAM D11 */
@ -340,6 +448,7 @@ struct samd_descr samd_parse_device_id(uint32_t did)
}
samd.pin = 'D';
samd.mem = 14 - (devsel % 3);
samd.variant = 'A';
break;
}
@ -389,15 +498,19 @@ bool samd_probe(target *t)
/* Part String */
if (protected) {
snprintf(variant_string, sizeof(variant_string),
"Atmel SAMD%d%c%dA%s (rev %c) (PROT=1)",
samd.series, samd.pin, samd.mem,
samd.package, samd.revision);
sprintf(variant_string,
"Atmel SAM%c%d%c%d%c%s (rev %c) (PROT=1)",
samd.family,
samd.series, samd.pin, samd.mem,
samd.variant,
samd.package, samd.revision);
} else {
snprintf(variant_string, sizeof(variant_string),
"Atmel SAMD%d%c%dA%s (rev %c)",
samd.series, samd.pin, samd.mem,
samd.package, samd.revision);
sprintf(variant_string,
"Atmel SAM%c%d%c%d%c%s (rev %c)",
samd.family,
samd.series, samd.pin, samd.mem,
samd.variant,
samd.package, samd.revision);
}
/* Setup Target */