1 /** 2 * \file 3 * 4 * \brief Matrix driver for SAM. 5 * 6 * Copyright (c) 2012-2015 Atmel Corporation. All rights reserved. 7 * 8 * \asf_license_start 9 * 10 * \page License 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions are met: 14 * 15 * 1. Redistributions of source code must retain the above copyright notice, 16 * this list of conditions and the following disclaimer. 17 * 18 * 2. Redistributions in binary form must reproduce the above copyright notice, 19 * this list of conditions and the following disclaimer in the documentation 20 * and/or other materials provided with the distribution. 21 * 22 * 3. The name of Atmel may not be used to endorse or promote products derived 23 * from this software without specific prior written permission. 24 * 25 * 4. This software may only be redistributed and used in connection with an 26 * Atmel microcontroller product. 27 * 28 * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED 29 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 30 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE 31 * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR 32 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 36 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 37 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 38 * POSSIBILITY OF SUCH DAMAGE. 39 * 40 * \asf_license_stop 41 * 42 */ 43 /* 44 * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a> 45 */ 46 47 #include "matrix.h" 48 49 /* / @cond 0 */ 50 /**INDENT-OFF**/ 51 #ifdef __cplusplus 52 extern "C" { 53 #endif 54 /**INDENT-ON**/ 55 /* / @endcond */ 56 57 /** 58 * \defgroup sam_drivers_matrix_group Matrix (MATRIX) 59 * 60 * \par Purpose 61 * 62 * The Bus Matrix implements a multi-layer AHB that enables parallel access 63 * paths between multiple AHB masters and slaves in a system, which increases 64 * the overall bandwidth. 65 * 66 * @{ 67 */ 68 69 #if SAM4C 70 #ifdef SAM4C_0 71 #define MATRIX MATRIX0 72 #else 73 #define MATRIX MATRIX1 74 #endif 75 #endif 76 77 #if SAM4CP 78 #ifdef SAM4CP_0 79 #define MATRIX MATRIX0 80 #else 81 #define MATRIX MATRIX1 82 #endif 83 #endif 84 85 #if SAM4CM 86 #ifdef SAM4CM_0 87 #define MATRIX MATRIX0 88 #else 89 #define MATRIX MATRIX1 90 #endif 91 #endif 92 93 #ifndef MATRIX_WPMR_WPKEY_PASSWD 94 #define MATRIX_WPMR_WPKEY_PASSWD MATRIX_WPMR_WPKEY(0x4D4154U) 95 #endif 96 97 /** 98 * \brief Set undefined length burst type of the specified master. 99 * 100 * \param ul_id Master index. 101 * \param burst_type Undefined length burst type. 102 */ 103 void matrix_set_master_burst_type(uint32_t ul_id, burst_type_t burst_type) 104 { 105 #if (SAMV70 || SAMS70|| SAME70) 106 Matrix *p_matrix = MATRIX; 107 volatile uint32_t *p_MCFG; 108 volatile uint32_t ul_reg; 109 uint32_t ul_dlt; 110 111 ul_dlt = (uint32_t)&(p_matrix->MATRIX_MCFG1); 112 ul_dlt = ul_dlt - (uint32_t)&(p_matrix->MATRIX_MCFG0); 113 114 p_MCFG = (volatile uint32_t *)((uint32_t)&(p_matrix->MATRIX_MCFG0) + 115 ul_id * ul_dlt); 116 117 ul_reg = *p_MCFG & (~MATRIX_MCFG0_ULBT_Msk); 118 *p_MCFG = ul_reg | (uint32_t)burst_type; 119 #else 120 Matrix *p_matrix = MATRIX; 121 volatile uint32_t ul_reg; 122 123 ul_reg = p_matrix->MATRIX_MCFG[ul_id] & (~MATRIX_MCFG_ULBT_Msk); 124 p_matrix->MATRIX_MCFG[ul_id] = ul_reg | (uint32_t)burst_type; 125 #endif 126 } 127 128 /** 129 * \brief Get undefined length burst type of the specified master. 130 * 131 * \param ul_id Master index. 132 * 133 * \return Undefined length burst type. 134 */ 135 burst_type_t matrix_get_master_burst_type(uint32_t ul_id) 136 { 137 #if (SAMV70 || SAMS70|| SAME70) 138 Matrix *p_matrix = MATRIX; 139 volatile uint32_t *p_MCFG; 140 volatile uint32_t ul_reg; 141 uint32_t ul_dlt; 142 143 ul_dlt = (uint32_t)&(p_matrix->MATRIX_MCFG1); 144 ul_dlt = ul_dlt - (uint32_t)&(p_matrix->MATRIX_MCFG0); 145 146 p_MCFG = (volatile uint32_t *)((uint32_t)&(p_matrix->MATRIX_MCFG0) + 147 ul_id * ul_dlt); 148 149 ul_reg = *p_MCFG & (~MATRIX_MCFG0_ULBT_Msk); 150 return (burst_type_t)ul_reg; 151 #else 152 Matrix *p_matrix = MATRIX; 153 volatile uint32_t ul_reg; 154 155 ul_reg = p_matrix->MATRIX_MCFG[ul_id] & (MATRIX_MCFG_ULBT_Msk); 156 return (burst_type_t)ul_reg; 157 #endif 158 } 159 160 /** 161 * \brief Set slot cycle of the specified slave. 162 * 163 * \param ul_id Slave index. 164 * \param ul_slot_cycle Number of slot cycle. 165 */ 166 void matrix_set_slave_slot_cycle(uint32_t ul_id, uint32_t ul_slot_cycle) 167 { 168 Matrix *p_matrix = MATRIX; 169 volatile uint32_t ul_reg; 170 171 ul_reg = p_matrix->MATRIX_SCFG[ul_id] & (~MATRIX_SCFG_SLOT_CYCLE_Msk); 172 p_matrix->MATRIX_SCFG[ul_id] = ul_reg | MATRIX_SCFG_SLOT_CYCLE( 173 ul_slot_cycle); 174 } 175 176 /** 177 * \brief Get slot cycle of the specified slave. 178 * 179 * \param ul_id Slave index. 180 * 181 * \return Number of slot cycle. 182 */ 183 uint32_t matrix_get_slave_slot_cycle(uint32_t ul_id) 184 { 185 Matrix *p_matrix = MATRIX; 186 volatile uint32_t ul_reg; 187 188 ul_reg = p_matrix->MATRIX_SCFG[ul_id] & (MATRIX_SCFG_SLOT_CYCLE_Msk); 189 return (ul_reg >> MATRIX_SCFG_SLOT_CYCLE_Pos); 190 } 191 192 /** 193 * \brief Set default master type of the specified slave. 194 * 195 * \param ul_id Slave index. 196 * \param type Default master type. 197 */ 198 void matrix_set_slave_default_master_type(uint32_t ul_id, defaut_master_t type) 199 { 200 Matrix *p_matrix = MATRIX; 201 volatile uint32_t ul_reg; 202 203 ul_reg = p_matrix->MATRIX_SCFG[ul_id] & (~MATRIX_SCFG_DEFMSTR_TYPE_Msk); 204 p_matrix->MATRIX_SCFG[ul_id] = ul_reg | (uint32_t)type; 205 } 206 207 /** 208 * \brief Get default master type of the specified slave. 209 * 210 * \param ul_id Slave index. 211 * 212 * \return Default master type. 213 */ 214 defaut_master_t matrix_get_slave_default_master_type(uint32_t ul_id) 215 { 216 Matrix *p_matrix = MATRIX; 217 volatile uint32_t ul_reg; 218 219 ul_reg = p_matrix->MATRIX_SCFG[ul_id] & (MATRIX_SCFG_DEFMSTR_TYPE_Msk); 220 return (defaut_master_t)ul_reg; 221 } 222 223 /** 224 * \brief Set fixed default master of the specified slave. 225 * 226 * \param ul_id Slave index. 227 * \param ul_fixed_id Fixed default master index. 228 */ 229 void matrix_set_slave_fixed_default_master(uint32_t ul_id, uint32_t ul_fixed_id) 230 { 231 Matrix *p_matrix = MATRIX; 232 volatile uint32_t ul_reg; 233 234 ul_reg = p_matrix->MATRIX_SCFG[ul_id] & 235 (~MATRIX_SCFG_FIXED_DEFMSTR_Msk); 236 p_matrix->MATRIX_SCFG[ul_id] 237 = ul_reg | MATRIX_SCFG_FIXED_DEFMSTR(ul_fixed_id); 238 } 239 240 /** 241 * \brief Get fixed default master of the specified slave. 242 * 243 * \param ul_id Slave index. 244 * 245 * \return Fixed default master index. 246 */ 247 uint32_t matrix_get_slave_fixed_default_master(uint32_t ul_id) 248 { 249 Matrix *p_matrix = MATRIX; 250 volatile uint32_t ul_reg; 251 252 ul_reg = p_matrix->MATRIX_SCFG[ul_id] & (MATRIX_SCFG_FIXED_DEFMSTR_Msk); 253 return (ul_reg >> MATRIX_SCFG_FIXED_DEFMSTR_Pos); 254 } 255 256 #if !SAM4E && !SAM4C && !SAM4CP && !SAM4CM && \ 257 !SAMV71 && !SAMV70 && !SAMS70 && !SAME70 258 /** 259 * \brief Set slave arbitration type of the specified slave. 260 * 261 * \param ul_id Slave index. 262 * \param type Arbitration type. 263 */ 264 void matrix_set_slave_arbitration_type(uint32_t ul_id, arbitration_type_t type) 265 { 266 Matrix *p_matrix = MATRIX; 267 volatile uint32_t ul_reg; 268 269 ul_reg = p_matrix->MATRIX_SCFG[ul_id] & (~MATRIX_SCFG_ARBT_Msk); 270 p_matrix->MATRIX_SCFG[ul_id] = ul_reg | (uint32_t)type; 271 } 272 273 /** 274 * \brief Get slave arbitration type of the specified slave. 275 * 276 * \param ul_id Slave index. 277 * 278 * \return Arbitration type. 279 */ 280 arbitration_type_t matrix_get_slave_arbitration_type(uint32_t ul_id) 281 { 282 Matrix *p_matrix = MATRIX; 283 volatile uint32_t ul_reg; 284 285 ul_reg = p_matrix->MATRIX_SCFG[ul_id] & (MATRIX_SCFG_ARBT_Msk); 286 return (arbitration_type_t)ul_reg; 287 } 288 289 #endif 290 291 /** 292 * \brief Set priority for the specified slave access. 293 * 294 * \param ul_id Slave index. 295 * \param ul_prio Bitmask OR of priorities of master x. 296 */ 297 void matrix_set_slave_priority(uint32_t ul_id, uint32_t ul_prio) 298 { 299 #if (SAMV71 || SAMV70|| SAME70) 300 Matrix *p_matrix = MATRIX; 301 p_matrix->MATRIX_PR[ul_id].MATRIX_PRAS = ul_prio; 302 #else 303 Matrix *p_matrix = MATRIX; 304 volatile uint32_t *p_PRAS; 305 uint32_t ul_dlt; 306 307 ul_dlt = (uint32_t)&(p_matrix->MATRIX_PRAS1); 308 ul_dlt = ul_dlt - (uint32_t)&(p_matrix->MATRIX_PRAS0); 309 310 p_PRAS = (volatile uint32_t *)((uint32_t)&(p_matrix->MATRIX_PRAS0) + 311 ul_id * ul_dlt); 312 313 *p_PRAS = ul_prio; 314 #endif 315 } 316 317 /** 318 * \brief Get priority for the specified slave access. 319 * 320 * \param ul_id Slave index. 321 * 322 * \return Bitmask OR of priorities of master x. 323 */ 324 uint32_t matrix_get_slave_priority(uint32_t ul_id) 325 { 326 #if (SAMV71 || SAMV70|| SAME70) 327 Matrix *p_matrix = MATRIX; 328 return p_matrix->MATRIX_PR[ul_id].MATRIX_PRAS; 329 #else 330 Matrix *p_matrix = MATRIX; 331 volatile uint32_t *p_PRAS; 332 uint32_t ul_dlt; 333 334 ul_dlt = (uint32_t)&(p_matrix->MATRIX_PRAS1); 335 ul_dlt = ul_dlt - (uint32_t)&(p_matrix->MATRIX_PRAS0); 336 337 p_PRAS = (volatile uint32_t *)((uint32_t)&(p_matrix->MATRIX_PRAS0) + 338 ul_id * ul_dlt); 339 340 return (*p_PRAS); 341 #endif 342 } 343 344 #if (SAMV71 || SAMV70|| SAME70 || SAMS70) 345 /** 346 * \brief Set priority for the specified slave access. 347 * 348 * \param ul_id Slave index. 349 * \param ul_prio_b Bitmask OR of priorities of master x. 350 */ 351 void matrix_set_slave_priority_b(uint32_t ul_id, uint32_t ul_prio_b) 352 { 353 #if (SAMV71 || SAMV70|| SAME70) 354 Matrix *p_matrix = MATRIX; 355 p_matrix->MATRIX_PR[ul_id].MATRIX_PRBS = ul_prio_b; 356 #else 357 Matrix *p_matrix = MATRIX; 358 volatile uint32_t *p_PRAS; 359 uint32_t ul_dlt; 360 361 ul_dlt = (uint32_t)&(p_matrix->MATRIX_PRBS1); 362 ul_dlt = ul_dlt - (uint32_t)&(p_matrix->MATRIX_PRBS0); 363 364 p_PRAS = (volatile uint32_t *)((uint32_t)&(p_matrix->MATRIX_PRBS0) + 365 ul_id * ul_dlt); 366 367 *p_PRAS = ul_prio; 368 #endif 369 } 370 371 /** 372 * \brief Get priority for the specified slave access. 373 * 374 * \param ul_id Slave index. 375 * 376 * \return Bitmask OR of priorities of master x. 377 */ 378 uint32_t matrix_get_slave_priority_b(uint32_t ul_id) 379 { 380 #if (SAMV71 || SAMV70|| SAME70) 381 Matrix *p_matrix = MATRIX; 382 return p_matrix->MATRIX_PR[ul_id].MATRIX_PRBS; 383 #else 384 Matrix *p_matrix = MATRIX; 385 volatile uint32_t *p_PRAS; 386 uint32_t ul_dlt; 387 388 ul_dlt = (uint32_t)&(p_matrix->MATRIX_PRBS1); 389 ul_dlt = ul_dlt - (uint32_t)&(p_matrix->MATRIX_PRBS0); 390 391 p_PRAS = (volatile uint32_t *)((uint32_t)&(p_matrix->MATRIX_PRBS0) + 392 ul_id * ul_dlt); 393 394 return (*p_PRAS); 395 #endif 396 } 397 #endif 398 399 #if (SAM3XA || SAM3U || SAM4E ||\ 400 SAMV71 || SAMV70 || SAMS70 || SAME70) 401 /** 402 * \brief Set bus matrix master remap. 403 * 404 * \param ul_remap Bitmask OR of RCBx: 0 for disable, 1 for enable. 405 */ 406 void matrix_set_master_remap(uint32_t ul_remap) 407 { 408 Matrix *p_matrix = MATRIX; 409 410 p_matrix->MATRIX_MRCR = ul_remap; 411 } 412 413 /** 414 * \brief Get bus matrix master remap. 415 * 416 * \return Bitmask OR of RCBx: 0 for disable, 1 for enable. 417 */ 418 uint32_t matrix_get_master_remap(void) 419 { 420 Matrix *p_matrix = MATRIX; 421 422 return (p_matrix->MATRIX_MRCR); 423 } 424 425 #endif 426 427 #if (SAM3S || SAM3XA || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM || \ 428 SAMV71 || SAMV70 || SAMS70 || SAME70) 429 /** 430 * \brief Set system IO. 431 * 432 * \param ul_io Bitmask OR of SYSIOx. 433 */ 434 void matrix_set_system_io(uint32_t ul_io) 435 { 436 Matrix *p_matrix = MATRIX; 437 438 #if (SAM4C || SAM4CP || SAM4CM) 439 440 p_matrix->MATRIX_SYSIO = ul_io; 441 442 #elif (SAMV71 || SAMV70 || SAMS70 || SAME70) 443 444 p_matrix->CCFG_SYSIO &= 0xFFFF0000; 445 p_matrix->CCFG_SYSIO |= (ul_io & 0xFFFF); 446 447 #else 448 449 p_matrix->CCFG_SYSIO = ul_io; 450 451 #endif 452 453 } 454 455 /** 456 * \brief Get system IO. 457 * 458 * \return Bitmask OR of SYSIOx. 459 */ 460 uint32_t matrix_get_system_io(void) 461 { 462 Matrix *p_matrix = MATRIX; 463 464 #if (SAM4C || SAM4CP || SAM4CM) 465 466 return (p_matrix->MATRIX_SYSIO); 467 468 #elif (SAMV71 || SAMV70 || SAMS70 || SAME70) 469 470 return (p_matrix->CCFG_SYSIO & 0xFFFF); 471 472 #else 473 474 return (p_matrix->CCFG_SYSIO); 475 476 #endif 477 } 478 479 #endif 480 481 #if (SAM3S || SAM4S || SAM4E || SAM4C || SAM4CP || SAM4CM || \ 482 SAMV71 || SAMV70 || SAMS70 || SAME70) 483 /** 484 * \brief Set NAND Flash Chip Select configuration register. 485 * 486 * \param ul_cs Bitmask OR of SMC_NFCSx: 0 if NCSx is not assigned, 487 * 1 if NCSx is assigned. 488 */ 489 void matrix_set_nandflash_cs(uint32_t ul_cs) 490 { 491 Matrix *p_matrix = MATRIX; 492 493 494 #if (SAM4C || SAM4CP || SAM4CM) 495 496 p_matrix->MATRIX_SMCNFCS = ul_cs; 497 498 #else 499 500 p_matrix->CCFG_SMCNFCS = ul_cs; 501 502 #endif 503 } 504 505 /** 506 * \brief Get NAND Flash Chip Select configuration register. 507 * 508 * \return Bitmask OR of SMC_NFCSx. 509 */ 510 uint32_t matrix_get_nandflash_cs(void) 511 { 512 Matrix *p_matrix = MATRIX; 513 514 #if (SAM4C || SAM4CP || SAM4CM) 515 516 return (p_matrix->MATRIX_SMCNFCS); 517 518 #else 519 520 return (p_matrix->CCFG_SMCNFCS); 521 522 #endif 523 } 524 525 #endif 526 527 #if (!SAMG) 528 /** 529 * \brief Enable or disable write protect of MATRIX registers. 530 * 531 * \param ul_enable 1 to enable, 0 to disable. 532 */ 533 void matrix_set_writeprotect(uint32_t ul_enable) 534 { 535 Matrix *p_matrix = MATRIX; 536 537 if (ul_enable) { 538 p_matrix->MATRIX_WPMR = MATRIX_WPMR_WPKEY_PASSWD | MATRIX_WPMR_WPEN; 539 } else { 540 p_matrix->MATRIX_WPMR = MATRIX_WPMR_WPKEY_PASSWD; 541 } 542 } 543 544 /** 545 * \brief Get write protect status. 546 * 547 * \return Write protect status. 548 */ 549 uint32_t matrix_get_writeprotect_status(void) 550 { 551 Matrix *p_matrix = MATRIX; 552 553 return (p_matrix->MATRIX_WPSR); 554 } 555 #endif 556 557 #if SAMG55 558 /** 559 * \brief Set USB device mode. 560 * 561 */ 562 void matrix_set_usb_device(void) 563 { 564 Matrix *p_matrix = MATRIX; 565 566 p_matrix->CCFG_SYSIO &= ~(CCFG_SYSIO_SYSIO10 | CCFG_SYSIO_SYSIO11); 567 568 p_matrix->CCFG_USBMR |= CCFG_USBMR_DEVICE; 569 } 570 571 /** 572 * \brief Set USB device mode. 573 * 574 */ 575 void matrix_set_usb_host(void) 576 { 577 Matrix *p_matrix = MATRIX; 578 579 p_matrix->CCFG_SYSIO &= ~(CCFG_SYSIO_SYSIO10 | CCFG_SYSIO_SYSIO11); 580 581 p_matrix->CCFG_USBMR &= ~CCFG_USBMR_DEVICE; 582 } 583 #endif 584 585 #if (SAMV71 || SAMV70|| SAME70) 586 /** 587 * \brief Set CAN0 DMA base address. 588 * 589 * \param base_addr the 16-bit MSB of the CAN0 DMA base address. 590 */ 591 void matrix_set_can0_addr(uint32_t base_addr) 592 { 593 Matrix *p_matrix = MATRIX; 594 p_matrix->CCFG_CAN0 = CCFG_CAN0_CAN0DMABA(base_addr); 595 } 596 597 /** 598 * \brief Set CAN1 DMA base address. 599 * 600 * \param base_addr the 16-bit MSB of the CAN1 DMA base address. 601 */ 602 void matrix_set_can1_addr(uint32_t base_addr) 603 { 604 Matrix *p_matrix = MATRIX; 605 volatile uint32_t ul_reg; 606 607 ul_reg = p_matrix->CCFG_SYSIO & (~CCFG_SYSIO_CAN1DMABA_Msk); 608 p_matrix->CCFG_SYSIO = ul_reg | CCFG_SYSIO_CAN1DMABA(base_addr); 609 } 610 #endif 611 612 /* @} */ 613 614 /* / @cond 0 */ 615 /**INDENT-OFF**/ 616 #ifdef __cplusplus 617 } 618 #endif 619 /**INDENT-ON**/ 620 /* / @endcond */ 621