samd: Add support for L21 & L22 (PR #345)
This commit is contained in:
parent
04d9749f25
commit
67f9d26644
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue