- Timestamp:
- Jan 31, 2014, 2:37:38 PM (11 years ago)
- Location:
- branch/giet_vm_ioc_drivers/giet_drivers
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
branch/giet_vm_ioc_drivers/giet_drivers/bdv_driver.c
r283 r284 1 1 /////////////////////////////////////////////////////////////////////////////////// 2 // File : ioc_driver.c 3 // Date : 23/05/2013 4 // Author : alain greiner 2 // File : bdv_driver.c 3 // Date : 23/05/2013 4 // Author : alain greiner 5 // Maintainer: cesar fuguet 5 6 // Copyright (c) UPMC-LIP6 6 7 /////////////////////////////////////////////////////////////////////////////////// 7 // The ioc_driver.c and ioc_driver.h files are part ot the GIET-VM kernel.8 // The bdv_driver.c and bdv_driver.h files are part ot the GIET-VM kernel. 8 9 // This driver supports the SocLib vci_block_device component, that is 9 10 // a single channel, block oriented, external storage contrÃŽler. … … 14 15 // that is always blocking, but can be called in 4 modes: 15 16 // 16 // - In BOOT_PA mode, the _bdv_access() function use the buffer virtual address 17 // as a physical address (as the page tables are not build) and use a polling 18 // policy on the IOC_STATUS register to detect transfer completion, as 19 // hardware interrupts are not activated. This mode is used by the 20 // boot code to load the map.bin file into memory. 21 // 22 // - In BOOT_VA mode, the _bdv_access() function makes a V2P translation to 23 // compute the buffer physical address, and use a polling policy on IOC_STATUS 24 // register to detect transfer completion. This mode is used by the boot code 25 // to load the various .elf files into memory. 26 // 27 // - In KERNEL mode, the _bdv_access() function makes a V2P translation to 28 // compute the buffer physical address, and use a descheduling strategy: 29 // The ISR executed when transfer completes should restart the calling task. 30 // There is no checking of user access right to the memory buffer. 31 // This mode must be used to access IOC, for an "open" system call. 32 // 33 // - In USER mode, the _bdv_access() function makes a V2P translation to 34 // compute the buffer physical address, and use a descheduling strategy: 17 // - In BOOT_PA mode, the _bdv_access() function uses a polling policy on the 18 // IOC_STATUS register to detect transfer completion, as hardware interrupts 19 // are not activated. This mode is used by the boot code to load the map.bin 20 // file into memory. 21 // 22 // - In BOOT_VA mode, the _bdv_access() function uses a polling policy on 23 // IOC_STATUS register to detect transfer completion. This mode is used by 24 // the boot code to load the various .elf files into memory. 25 // 26 // - In KERNEL mode, the _bdv_access() function uses a descheduling strategy: 27 // The ISR executed when transfer completes should restart the calling task. 28 // There is no checking of user access right to the memory buffer. This mode 29 // must be used to access IOC, for an "open" system call. 30 // 31 // - In USER mode, the _bdv_access() function uses a descheduling strategy: 35 32 // The ISR executed when transfer completes should restart the calling task, 36 33 // The user access right to the memory buffer must be checked. 37 34 // This mode must be used to access IOC, for a "read/write" system call. 38 35 // 39 // As the IOCcomponent can be used by several programs running in parallel,36 // As the BDV component can be used by several programs running in parallel, 40 37 // the _ioc_lock variable guaranties exclusive access to the device. The 41 38 // _bdv_read() and _bdv_write() functions use atomic LL/SC to get the lock. 42 //43 // The IOMMU can be activated or not:44 //45 // 1) When the IOMMU is used, a fixed size 2Mbytes vseg is allocated to46 // the IOC peripheral, in the I/O virtual space, and the user buffer is47 // dynamically remapped in the IOMMU page table. The corresponding entry48 // in the IOMMU PT1 is defined by the kernel _ioc_iommu_ix1 variable.49 // The number of pages to be unmapped is stored in the _ioc_npages variable.50 // The number of PT2 entries is dynamically computed and stored in the51 // kernel _ioc_iommu_npages variable. It cannot be larger than 512.52 // The user buffer is unmapped by the _ioc_completed() function when53 // the transfer is completed.54 //55 // 2/ If the IOMMU is not used, we check that the user buffer is mapped to a56 // contiguous physical buffer (this is generally true because the user space57 // page tables are statically constructed to use contiguous physical memory).58 39 // 59 40 // Finally, the memory buffer must fulfill the following conditions: -
branch/giet_vm_ioc_drivers/giet_drivers/ioc_driver.c
r283 r284 1 1 /////////////////////////////////////////////////////////////////////////////////// 2 // File : ioc_driver.c 3 // Date : 23/05/2013 4 // Author : alain greiner 2 // File : ioc_driver.c 3 // Date : 23/05/2013 4 // Author : alain greiner 5 // Maintainer : cesar fuguet 5 6 // Copyright (c) UPMC-LIP6 6 7 /////////////////////////////////////////////////////////////////////////////////// … … 12 13 // 13 14 // The _ioc_read() and _ioc_write() functions use the _ioc_access() function, 14 // that is always blocking , but can be called in 4 modes:15 // 16 // - In BOOT_PA mode, the _ioc_access() function use the buffer virtual address17 // as a physical address (as the page tables are not build) and use a polling18 // policy on the IOC_STATUS register to detect transfer completion, as19 // hardware interrupts are not activated. This mode is used by the20 // boot code to load the map.bin file into memory.15 // that is always blocking. The _ioc_access function will call the read or 16 // write function in the driver of the choosen IOC peripheral, which can be for 17 // now: BDV, HBA and SPI. This function can be called in 4 modes: 18 // 19 // - In BOOT_PA mode, the _ioc_access() function use the buffer virtual address 20 // as a physical address (as the page tables are not build). This mode is 21 // used by the boot code to load the map.bin file into memory. 21 22 // 22 23 // - In BOOT_VA mode, the _ioc_access() function makes a V2P translation to 23 // compute the buffer physical address, and use a polling policy on IOC_STATUS 24 // register to detect transfer completion. This mode is used by the boot code 25 // to load the various .elf files into memory. 24 // compute the buffer physical address. This mode is used by the boot code to 25 // load the various .elf files into memory. 26 26 // 27 27 // - In KERNEL mode, the _ioc_access() function makes a V2P translation to 28 // compute the buffer physical address, and use a descheduling strategy: 29 // The ISR executed when transfer completes should restart the calling task. 30 // There is no checking of user access right to the memory buffer. 31 // This mode must be used to access IOC, for an "open" system call. 28 // compute the buffer physical address. There is no checking of user access 29 // right to the memory buffer. This mode must be used to access IOC, for an 30 // "open" system call. 32 31 // 33 32 // - In USER mode, the _ioc_access() function makes a V2P translation to 34 // compute the buffer physical address, and use a descheduling strategy: 35 // The ISR executed when transfer completes should restart the calling task, 36 // The user access right to the memory buffer must be checked. 37 // This mode must be used to access IOC, for a "read/write" system call. 38 // 39 // As the IOC component can be used by several programs running in parallel, 40 // the _ioc_lock variable guaranties exclusive access to the device. The 41 // _ioc_read() and _ioc_write() functions use atomic LL/SC to get the lock. 33 // compute the buffer physical address. The user access right to the memory 34 // buffer must be checked. This mode must be used to access IOC, for a 35 // "read/write" system call. 42 36 // 43 37 // The IOMMU can be activated or not: -
branch/giet_vm_ioc_drivers/giet_drivers/ioc_driver.h
r283 r284 6 6 /////////////////////////////////////////////////////////////////////////////////// 7 7 8 #ifndef _GIET_IOC_DRIVER S_H_9 #define _GIET_IOC_DRIVER S_H_8 #ifndef _GIET_IOC_DRIVER_H_ 9 #define _GIET_IOC_DRIVER_H_ 10 10 11 11 /////////////////////////////////////////////////////////////////////////////////// -
branch/giet_vm_ioc_drivers/giet_drivers/sdc_driver.c
r283 r284 1 /** 2 * \file : sdc_driver.c 3 * \date : 30 August 2012 4 * \author : Cesar Fuguet 5 * 6 * This file defines the driver of a SD Card device using an SPI controller 7 */ 8 1 /////////////////////////////////////////////////////////////////////////////////// 2 // File : sdc_driver.c 3 // Date : 31/08/2012 4 // Author : cesar fuguet 5 // Copyright (c) UPMC-LIP6 6 /////////////////////////////////////////////////////////////////////////////////// 9 7 #include <sdc_driver.h> 10 8 #include <utils.h> … … 16 14 static struct spi_dev* spi; 17 15 18 /** 19 * \return void 20 * 21 * \brief Enable SD Card select signal 22 */ 16 /////////////////////////////////////////////////////////////////////////////// 17 // _sdc_enable() 18 // This function enables SD Card select signal 19 /////////////////////////////////////////////////////////////////////////////// 23 20 static void _sdc_enable() 24 21 { … … 26 23 } 27 24 28 /** 29 * \return void 30 * 31 * \brief Disable SD Card select signal 32 */ 25 /////////////////////////////////////////////////////////////////////////////// 26 // _sdc_enable() 27 // This function disables SD Card select signal 28 /////////////////////////////////////////////////////////////////////////////// 33 29 static void _sdc_disable() 34 30 { … … 36 32 } 37 33 38 /** 39 * \param tick_count: SD Card clock ticks number 40 * 41 * \return void 42 * 43 * \brief Enable SD Card clock 44 * The tick count is byte measured (1 tick, 8 clock) 45 */ 34 /////////////////////////////////////////////////////////////////////////////// 35 // _sdc_gen_tick() 36 // This function writes on the SPI tx register to generate SD card clock ticks 37 // - tick_count: number of ticks to generate (1 tick -> 8 clocks) 38 /////////////////////////////////////////////////////////////////////////////// 46 39 static void _sdc_gen_tick(unsigned int tick_count) 47 40 { … … 50 43 } 51 44 52 /** 53 * \param lba : Position where the block device access 54 * pointer must be move 55 * 56 * \return void 57 * 58 * \brief Change block device access pointer position 59 * 60 * The block device access pointer is relocated in terms of blocks 61 */ 45 /////////////////////////////////////////////////////////////////////////////// 46 // _sdc_lseek() 47 // This function changes the SD card access pointer position in terms of 48 // blocks 49 // - lba: number of logical block to move the pointer 50 /////////////////////////////////////////////////////////////////////////////// 62 51 void _sdc_lseek(unsigned int lba) 63 52 { … … 65 54 } 66 55 67 /** 68 * \return char from the SD card 69 * 70 * \brief Get a byte from the SD Card 71 */ 56 /////////////////////////////////////////////////////////////////////////////// 57 // _sdc_receive_char() 58 // This function gets a byte from the SD card 59 /////////////////////////////////////////////////////////////////////////////// 72 60 static unsigned char _sdc_receive_char() 73 61 { … … 77 65 } 78 66 79 /** 80 * \return sdcard response 81 * 82 * \brief Wait for a valid response after the send of a command 83 * This function can return if one of the next two conditions are true: 84 * 1. Bit valid received 85 * 2. Timeout (not valid bit received after SDCARD_COMMAND_TIMEOUT 86 * wait ticks) 87 */ 67 /////////////////////////////////////////////////////////////////////////////// 68 // _sdc_wait_response() 69 // This function returns when a valid response from the SD card is received or 70 // a timeout has been triggered 71 // Returns the SD card response value 72 /////////////////////////////////////////////////////////////////////////////// 88 73 static unsigned char _sdc_wait_response() 89 74 { … … 105 90 } 106 91 107 /** 108 * \return void 109 * 110 * \brief Wait data block start marker 111 */ 92 /////////////////////////////////////////////////////////////////////////////// 93 // _sdc_wait_data_block() 94 // This function returns when a data block from the SD card is received (data 95 // block start marker received). 96 // It must be called after a read command 97 /////////////////////////////////////////////////////////////////////////////// 112 98 static void _sdc_wait_data_block() 113 99 { … … 115 101 } 116 102 117 /** 118 * \param index : SD card CMD index 119 * \param app : Type of command, 0 for normal command or 1 for 120 * application specific 121 * \param args : SD card CMD arguments 122 * 123 * \return response first byte 124 * 125 * \brief Send command to the SD card 126 */ 103 /////////////////////////////////////////////////////////////////////////////// 104 // _sdc_send_command() 105 // This function sends a command to the SD card 106 // - index: CMD index 107 // - app: type of command 108 // - args: CMD arguments vector 109 // - crc7: CRC (7 bits) to send 110 /////////////////////////////////////////////////////////////////////////////// 127 111 static int _sdc_send_command ( int index, 128 112 int app , … … 137 121 if (app == SDCARD_ACMD) 138 122 { 139 spi_put_tx(sdcard.spi, 0x40 | 55 , 0 );/ * CMD and START bit */140 spi_put_tx(sdcard.spi, 0x00 , 0 );/ * Argument[0] */141 spi_put_tx(sdcard.spi, 0x00 , 0 );/ * Argument[1] */142 spi_put_tx(sdcard.spi, 0x00 , 0 );/ * Argument[2] */143 spi_put_tx(sdcard.spi, 0x00 , 0 );/ * Argument[3] */144 spi_put_tx(sdcard.spi, 0x01 | (crc7 << 1), 0 );/ * END bit */123 spi_put_tx(sdcard.spi, 0x40 | 55 , 0 );// CMD and START bit 124 spi_put_tx(sdcard.spi, 0x00 , 0 );// Argument[0] 125 spi_put_tx(sdcard.spi, 0x00 , 0 );// Argument[1] 126 spi_put_tx(sdcard.spi, 0x00 , 0 );// Argument[2] 127 spi_put_tx(sdcard.spi, 0x00 , 0 );// Argument[3] 128 spi_put_tx(sdcard.spi, 0x01 | (crc7 << 1), 0 );// END bit 145 129 146 130 sdcard_rsp = _sdc_wait_response(); … … 165 149 } 166 150 151 /////////////////////////////////////////////////////////////////////////////// 152 // _sdc_open() 153 // This function initializes the SD card (reset procedure) 154 // - channel: channel index (only channel 0 is supported) 155 // Returns 0 if success, other value if failure 156 /////////////////////////////////////////////////////////////////////////////// 167 157 static int _sdc_open( unsigned int channel ) 168 158 { … … 174 164 sdcard.slave_id = channel; 175 165 176 /* 177 * Supply SD card ramp up time (min 74 cycles) 178 */ 166 // supply SD card ramp up time (min 74 cycles) 179 167 _sdc_gen_tick(10); 180 168 181 /* 182 * Assert slave select signal 183 * Send CMD0 (Reset Command) 184 * Deassert slave select signal 185 */ 169 // Assert slave select signal 170 // Send CMD0 (Reset Command) 171 // Deassert slave select signal 186 172 _sdc_enable(); 187 173 … … 199 185 200 186 _sdc_disable(); 201 /* 202 * send CMD8. If card is pre-v2, It will reply with illegal command. 203 * Otherwise we announce sdhc support. 204 */ 187 188 // send CMD8. If card is pre-v2, It will reply with illegal command. 189 // Otherwise we announce sdhc support. 205 190 _sdc_enable(); 206 191 args[0] = 0; … … 209 194 args[3] = 0x01; 210 195 sdcard_rsp = _sdc_send_command(8, SDCARD_CMD, args, 0x63); 211 if (!SDCARD_CHECK_R1_VALID(sdcard_rsp)) { 196 if (!SDCARD_CHECK_R1_VALID(sdcard_rsp)) 197 { 212 198 _puts("card CMD8 failed "); 213 199 return sdcard_rsp; 214 200 } 215 if (!SDCARD_CHECK_R1_ERROR(sdcard_rsp)) { 216 /* no error, command accepted. get whole reply */ 201 if (!SDCARD_CHECK_R1_ERROR(sdcard_rsp)) 202 { 203 // no error, command accepted. get whole reply 217 204 ersp = _sdc_receive_char(); 218 205 ersp = (ersp << 8) | _sdc_receive_char(); … … 220 207 ersp = (ersp << 8) | _sdc_receive_char(); 221 208 if ((ersp & 0xffff) != 0x0101) { 222 / * voltage mismatch */209 // voltage mismatch 223 210 _puts("card CMD8 mismatch: "); 224 211 _putx(ersp); … … 227 214 _puts("v2 or later "); 228 215 sdcard.sdhc = 1; 229 } else if ((sdcard_rsp & SDCARD_R1_ILLEGAL_CMD) == 0) { 230 /* other error */ 216 } 217 else if ((sdcard_rsp & SDCARD_R1_ILLEGAL_CMD) == 0) 218 { 219 // other error 231 220 _puts("card CMD8 error "); 232 221 return sdcard_rsp; 233 } else { 222 } 223 else 224 { 234 225 sdcard.sdhc = 0; 235 226 } 236 227 _sdc_disable(); 237 /* send CMD41, enabling the card */ 228 229 // send CMD41, enabling the card 238 230 _sdc_enable(); 239 231 args[0] = sdcard.sdhc ? 0x40: 0; … … 255 247 256 248 _sdc_disable(); 257 if (sdcard_rsp) { 249 if (sdcard_rsp) 250 { 258 251 _puts("SD ACMD41 failed "); 259 252 return sdcard_rsp; 260 253 } 261 if (sdcard.sdhc != 0) { 262 /* get the card capacity to see if it's really HC */ 254 if (sdcard.sdhc != 0) 255 { 256 // get the card capacity to see if it's really HC 263 257 _sdc_enable(); 264 258 args[0] = sdcard.sdhc ? 0x40: 0; … … 267 261 args[3] = 0; 268 262 sdcard_rsp = _sdc_send_command(58, SDCARD_CMD, args, 0x00); 269 if (sdcard_rsp) { 263 if (sdcard_rsp) 264 { 270 265 _puts("SD CMD58 failed "); 271 266 return sdcard_rsp; … … 275 270 ersp = (ersp << 8) | _sdc_receive_char(); 276 271 ersp = (ersp << 8) | _sdc_receive_char(); 277 if (ersp & 0x40000000) { 272 if (ersp & 0x40000000) 273 { 278 274 _puts("SDHC "); 279 } else { 275 } else 276 { 280 277 sdcard.sdhc = 0; 281 278 } … … 286 283 } 287 284 285 /////////////////////////////////////////////////////////////////////////////// 286 // _sdc_set_block_size() 287 // This function sets the block size in bytes of the SD card 288 // - len: block size in bytes (only 512 bytes supported) 289 // Returns 0 if success, other value if failure 290 /////////////////////////////////////////////////////////////////////////////// 288 291 static unsigned int _sdc_set_block_size(unsigned int len) 289 292 { … … 292 295 register int i; 293 296 294 /* 295 * For now, supported block size is 512 bytes 296 */ 297 // For now, supported block size is 512 bytes 297 298 if (len != 512) return 1; 298 299 299 /* 300 * When using high capacity SDCARD, the block_length is not a number of bytes 301 * but a number of blocks (transfer unit) 302 */ 300 // When using high capacity SDCARD, the block_length is not a number of bytes 301 // but a number of blocks (transfer unit) 303 302 if (sdcard.sdhc) 304 303 { … … 328 327 } 329 328 329 /////////////////////////////////////////////////////////////////////////////// 330 // _sdc_init() 331 // This function initializes the SPI controller and call sdc_open to 332 // initializes SD card 333 // - channel: channel to initialize (only channel 0 supported) 334 // Returns 0 if success, other value if failure 335 /////////////////////////////////////////////////////////////////////////////// 330 336 unsigned int _sdc_init( unsigned int channel ) 331 337 { 332 338 spi = (struct spi_dev*) &seg_ioc_base; 333 339 334 /** 335 * Initializing the SPI controller 336 */ 340 // initializing the SPI controller 337 341 _spi_init ( 338 342 spi , … … 344 348 ); 345 349 346 /** 347 * Initializing the SD Card 348 */ 350 // initializing the SD Card 349 351 unsigned int iter = 0; 350 352 unsigned char sdcard_rsp; … … 376 378 } 377 379 378 /** 379 * Set the block length of the SD Card 380 */ 380 // set the block length of the SD Card 381 381 sdcard_rsp = _sdc_set_block_size(512); 382 382 if (sdcard_rsp) … … 386 386 } 387 387 388 /** 389 * Incrementing SDCARD clock frequency for normal function 390 */ 388 // incrementing SDCARD clock frequency for normal function 391 389 _spi_init ( 392 390 spi , 393 10000000 , / **< SPI_clk 10 Mhz */394 SYSCLK_FREQ , / **< Sys_clk */395 -1 , / **< Charlen: 8 */391 10000000 , // SPI_clk 10 Mhz 392 SYSCLK_FREQ , // Sys_clk 393 -1 , // Charlen: 8 396 394 -1 , 397 395 -1 … … 450 448 } 451 449 452 /* 453 * Get the CRC16 (comes at the end of the data block) 454 */ 450 // Get the CRC16 (comes at the end of the data block) 455 451 _sdc_receive_char(); // first byte 456 452 _sdc_receive_char(); // second byte … … 464 460 } 465 461 462 /////////////////////////////////////////////////////////////////////////////// 463 // _sdc_write() (not supported for now) 464 // Transfer data from memory buffer to SD card device. 465 // - mode : BOOT / KERNEL / USER 466 // - lba : destination first block index on the SD card 467 // - buffer : base address of the memory buffer (must be word aligned) 468 // - count : number of blocks to be transfered. 469 // Returns 0 if success, > 0 if error. 470 /////////////////////////////////////////////////////////////////////////////// 466 471 unsigned int _sdc_write( unsigned int mode, 467 472 unsigned int lba, … … 472 477 } 473 478 479 /////////////////////////////////////////////////////////////////////////////// 480 // _sdc_get_status() 481 // Transfer data from memory buffer to SD card device. 482 // - channel: channel index 483 // - status: this pointer is used to transmit the status value to caller. 484 // Returns 0 if success, > 0 if error. 485 /////////////////////////////////////////////////////////////////////////////// 474 486 unsigned int _sdc_get_status( unsigned int channel , 475 487 unsigned int* status ) 476 488 { 477 return BLOCK_DEVICE_IDLE; 478 } 479 489 *status = BLOCK_DEVICE_IDLE; 490 491 return 0; 492 } 493 494 /////////////////////////////////////////////////////////////////////////////// 495 // _sdc_get_block_size() 496 // Returns the block size in bytes of the SD card 497 /////////////////////////////////////////////////////////////////////////////// 480 498 unsigned int _sdc_get_block_size() 481 499 { … … 484 502 } 485 503 486 487 488 /* 489 * vim: tabstop=4 : shiftwidth=4 : expandtab : softtabstop=4 490 */ 504 // Local Variables: 505 // tab-width: 4 506 // c-basic-offset: 4 507 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 508 // indent-tabs-mode: nil 509 // End: 510 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 -
branch/giet_vm_ioc_drivers/giet_drivers/sdc_driver.h
r283 r284 1 /** 2 * \file sdc_driver.h 3 * \date 30 August 2012 4 * \author Cesar fuguet <cesar.fuguet-tortolero@lip6.fr> 5 * 6 * This file defines the driver of a SD Card device using an SPI controller 7 */ 8 9 #ifndef SDC_DRIVER_H 10 #define SDC_DRIVER_H 1 /////////////////////////////////////////////////////////////////////////////////// 2 // File : sdc_driver.h 3 // Date : 31/08/2012 4 // Author : cesar fuguet 5 // Copyright (c) UPMC-LIP6 6 /////////////////////////////////////////////////////////////////////////////////// 7 #ifndef _GIET_SDC_DRIVER_H_ 8 #define _GIET_SDC_DRIVER_H_ 11 9 12 10 #include <ioc_driver.h> … … 14 12 #include <mapping_info.h> 15 13 16 / **17 * \brief SD Card type definition18 */14 /////////////////////////////////////////////////////////////////////////////// 15 // SD card structure definition 16 /////////////////////////////////////////////////////////////////////////////// 19 17 struct sdcard_dev 20 18 { 21 /** 22 * SPI controller pointer 23 */ 19 // SPI controller pointer 24 20 struct spi_dev * spi; 25 21 26 /** 27 * Block length of the SDCARD 28 */ 22 // block length of the SDCARD 29 23 unsigned int block_length; 30 24 31 /** 32 * Access pointer representing the offset in bytes used 33 * to read or write in the SDCARD. 34 * 35 * \note this driver is for cards SDSD, therefore this offset 36 * must be multiple of the block length 37 */ 25 // access pointer representing the offset in bytes used to read or write in 26 // the SDCARD. This driver is for cards SDSD, therefore this offset must be 27 // multiple of the block length 38 28 unsigned int access_pointer; 39 29 40 /** 41 * Slave ID. This ID represents the number of the slave select signal 42 * used in the hardware platform (SPI channel) 43 */ 44 int slave_id; 30 // slave ID. This ID represents the number of the slave select signal used 31 // in the hardware platform (SPI channel) 32 int slave_id; 45 33 46 / * is the card high capacity ? */34 // is the card high capacity ? 47 35 int sdhc; 48 36 }; … … 68 56 69 57 70 / **71 * SD Card constants72 */58 /////////////////////////////////////////////////////////////////////////////// 59 // SD card constants 60 /////////////////////////////////////////////////////////////////////////////// 73 61 74 / ** Number of retries after an unacknowledge command */75 #define SDCARD_COMMAND_TIMEOUT 62 // Number of retries after an unacknowledge command 63 #define SDCARD_COMMAND_TIMEOUT 100 76 64 77 / ** This command is a simple SD commmand */78 #define SDCARD_CMD 65 // This command is a simple SD commmand 66 #define SDCARD_CMD 0 79 67 80 / ** This is an application specific command */81 #define SDCARD_ACMD 68 // This is an application specific command 69 #define SDCARD_ACMD 1 82 70 83 / ** The transmition is done in the negative edge of the clock */84 #define SDCARD_TX_NEGEDGE 71 // The transmition is done in the negative edge of the clock 72 #define SDCARD_TX_NEGEDGE 0 85 73 86 / ** The transmition is done in the positive edge of the clock */87 #define SDCARD_TX_POSEDGE 74 // The transmition is done in the positive edge of the clock 75 #define SDCARD_TX_POSEDGE 1 88 76 89 / ** The reception is done in the negative edge of the clock */90 #define SDCARD_RX_NEGEDGE 77 // The reception is done in the negative edge of the clock 78 #define SDCARD_RX_NEGEDGE 0 91 79 92 / ** The reception is done in the positive edge of the clock */93 #define SDCARD_RX_POSEDGE 80 // The reception is done in the positive edge of the clock 81 #define SDCARD_RX_POSEDGE 1 94 82 95 / **96 * SD Card macros97 */83 /////////////////////////////////////////////////////////////////////////////// 84 // SD card macros 85 /////////////////////////////////////////////////////////////////////////////// 98 86 99 /** Check if the response is valid */ 87 /////////////////////////////////////////////////////////////////////////////// 88 // SDCARD_CHECK_R1_VALID() 89 // This macro checks if the SD card response is valid 90 // - x: SD card response 91 // Returns 1 if valid and 0 otherwise 92 /////////////////////////////////////////////////////////////////////////////// 100 93 #define SDCARD_CHECK_R1_VALID(x) (~x & SDCARD_R1_RSP_VALID) ? 1 : 0 101 94 102 / **103 * Check if there is an error in the response 104 * 105 * \note this macro must be used after verify that the response is 106 * valid 107 */95 /////////////////////////////////////////////////////////////////////////////// 96 // SDCARD_CHECK_R1_ERROR() 97 // This macro checks if there is an error in SD card response 98 // - x: SD card response 99 // Returns 1 if error and 0 otherwise 100 /////////////////////////////////////////////////////////////////////////////// 108 101 #define SDCARD_CHECK_R1_ERROR(x) ( x & 0x7E) ? 1 : 0 109 102 110 /** 111 * SD Card Response 1 (R1) format constants 112 */ 113 #define SDCARD_R1_IN_IDLE_STATE ( 1 << 0 ) /**< \brief R1 bit 0 */ 114 #define SDCARD_R1_ERASE_RESET ( 1 << 1 ) /**< \brief R1 bit 1 */ 115 #define SDCARD_R1_ILLEGAL_CMD ( 1 << 2 ) /**< \brief R1 bit 2 */ 116 #define SDCARD_R1_COM_CRC_ERR ( 1 << 3 ) /**< \brief R1 bit 3 */ 117 #define SDCARD_R1_ERASE_SEQ_ERR ( 1 << 4 ) /**< \brief R1 bit 4 */ 118 #define SDCARD_R1_ADDRESS_ERR ( 1 << 5 ) /**< \brief R1 bit 5 */ 119 #define SDCARD_R1_PARAMETER_ERR ( 1 << 6 ) /**< \brief R1 bit 6 */ 120 #define SDCARD_R1_RSP_VALID ( 1 << 7 ) /**< \brief R1 bit 7 */ 103 // SD card response 1 (R1) format constants 104 #define SDCARD_R1_IN_IDLE_STATE ( 1 << 0 ) // R1 bit 0 105 #define SDCARD_R1_ERASE_RESET ( 1 << 1 ) // R1 bit 1 106 #define SDCARD_R1_ILLEGAL_CMD ( 1 << 2 ) // R1 bit 2 107 #define SDCARD_R1_COM_CRC_ERR ( 1 << 3 ) // R1 bit 3 108 #define SDCARD_R1_ERASE_SEQ_ERR ( 1 << 4 ) // R1 bit 4 109 #define SDCARD_R1_ADDRESS_ERR ( 1 << 5 ) // R1 bit 5 110 #define SDCARD_R1_PARAMETER_ERR ( 1 << 6 ) // R1 bit 6 111 #define SDCARD_R1_RSP_VALID ( 1 << 7 ) // R1 bit 7 121 112 122 113 #endif 123 114 124 /* 125 * vim: tabstop=4 : shiftwidth=4 : expandtab : softtabstop=4 126 */ 115 // Local Variables: 116 // tab-width: 4 117 // c-basic-offset: 4 118 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 119 // indent-tabs-mode: nil 120 // End: 121 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 -
branch/giet_vm_ioc_drivers/giet_drivers/spi_driver.c
r283 r284 1 /** 2 * \file spi.c 3 * \date 31 August 2012 4 * \author Cesar Fuguet <cesar.fuguet-tortolero@lip6.fr> 5 */ 1 /////////////////////////////////////////////////////////////////////////////////// 2 // File : spi_driver.c 3 // Date : 31/08/2012 4 // Author : cesar fuguet 5 // Copyright (c) UPMC-LIP6 6 /////////////////////////////////////////////////////////////////////////////////// 6 7 #include <spi_driver.h> 7 8 #include <utils.h> 8 9 9 / **10 * \param x: input value 11 * 12 * \return byte-swapped value 13 * 14 * \brief byte-swap a 32bit word 15 */10 /////////////////////////////////////////////////////////////////////////////// 11 // bswap32() 12 // This function makes a byte swap for a 4 bytes word 13 // Arguments are: 14 // - x : word 15 // Returns the word x swapped 16 /////////////////////////////////////////////////////////////////////////////// 16 17 static unsigned int bswap32(unsigned int x) 17 18 { … … 24 25 } 25 26 26 /** 27 * \param spi : Initialized pointer to the SPI controller 28 * 29 * \brief Wait until the SPI controller has finished a transfer 30 * 31 * Wait until the GO_BUSY bit of the SPI controller be deasserted 32 */ 27 /////////////////////////////////////////////////////////////////////////////// 28 // _spi_wait_if_busy() 29 // This function returns when the SPI controller has finished a transfer 30 // Arguments are: 31 // - spi : initialized pointer to the SPI controller 32 /////////////////////////////////////////////////////////////////////////////// 33 33 static void _spi_wait_if_busy(struct spi_dev * spi) 34 34 { … … 41 41 } 42 42 43 /** 44 * \param spi : Initialized pointer to the SPI controller 45 * 46 * \return void 47 * 48 * \brief Init transfer of the tx registers to the selected slaves 49 */ 43 /////////////////////////////////////////////////////////////////////////////// 44 // _spi_init_transfer() 45 // This function trigger transfer of the tx registers to the selected slaves 46 // Arguments are: 47 // - spi : initialized pointer to the SPI controller 48 /////////////////////////////////////////////////////////////////////////////// 50 49 static void _spi_init_transfer(struct spi_dev * spi) 51 50 { … … 55 54 } 56 55 57 /** 58 * \param spi_freq : Desired frequency for the generated clock from the SPI 59 * controller 60 * \param sys_freq : System clock frequency 61 * 62 * \brief Calculated the value for the divider register in order to obtain the SPI 63 * desired clock frequency 64 */ 56 /////////////////////////////////////////////////////////////////////////////// 57 // _spi_calc_divider_value() 58 // This function computes the value for the divider register in order to obtain 59 // the SPI desired clock frequency 60 // - spi_freq : desired frequency for the generated clock from the SPI 61 // controller 62 // - sys_freq : system clock frequency 63 // Returns the computed frequency 64 /////////////////////////////////////////////////////////////////////////////// 65 65 static unsigned int _spi_calc_divider_value( unsigned int spi_freq , 66 66 unsigned int sys_freq ) … … 69 69 } 70 70 71 /////////////////////////////////////////////////////////////////////////////// 72 // spi_put_tx() 73 // This function writes a byte on the tx register and trigger transfert 74 // - spi : initialized pointer to the SPI controller 75 // - byte : byte to write on tx register 76 // - index: index of the tx register 77 /////////////////////////////////////////////////////////////////////////////// 71 78 void spi_put_tx(struct spi_dev * spi, unsigned char byte, int index) 72 79 { … … 79 86 } 80 87 88 /////////////////////////////////////////////////////////////////////////////// 89 // spi_get_rx() 90 // This function reads a byte on the rx register 91 // - spi : initialized pointer to the SPI controller 92 // - index: index of the rx register 93 // Returns the byte read 94 /////////////////////////////////////////////////////////////////////////////// 81 95 volatile unsigned char spi_get_rx(struct spi_dev * spi, int index) 82 96 { … … 84 98 } 85 99 100 /////////////////////////////////////////////////////////////////////////////// 101 // spi_get_data() 102 // This function reads count bytes and store them on a memory buffer 103 // - spi : initialized pointer to the SPI controller 104 // - buffer: physical address of the buffer containing the read data 105 // - count : number of bytes to get (must be 512 bytes) 106 // Returns 0 if success and other value when failure 107 /////////////////////////////////////////////////////////////////////////////// 86 108 unsigned int spi_get_data( struct spi_dev * spi, 87 109 paddr_t buffer , … … 161 183 } 162 184 163 //reset_ctrl: 185 #if 0 186 reset_ctrl: 187 #endif 164 188 165 189 /* Switch back to original word size */ … … 169 193 } 170 194 195 /////////////////////////////////////////////////////////////////////////////// 196 // spi_ss_assert() 197 // This function enables a SPI slave 198 // - spi : initialized pointer to the SPI controller 199 // - index : slave index 200 /////////////////////////////////////////////////////////////////////////////// 171 201 void spi_ss_assert(struct spi_dev * spi, int index) 172 202 { … … 176 206 } 177 207 208 /////////////////////////////////////////////////////////////////////////////// 209 // spi_ss_deassert() 210 // This function disables a SPI slave 211 // - spi : initialized pointer to the SPI controller 212 // - index : slave index 213 /////////////////////////////////////////////////////////////////////////////// 178 214 void spi_ss_deassert(struct spi_dev * spi, int index) 179 215 { … … 183 219 } 184 220 221 /////////////////////////////////////////////////////////////////////////////// 222 // _spi_init() 223 // This function initializes the configuration register of SPI controller 224 // - spi : initialized pointer to the SPI controller 225 // - spi_freq : SPI desired frequency (Hz) 226 // - sys_freq : system frequency (Hz) 227 // - char_len : bits per transfer 228 // - tx_edge : if 1, transfer on positive edge 229 // - rx_edge : if 1, latch received data on negative edge 230 /////////////////////////////////////////////////////////////////////////////// 185 231 void _spi_init ( struct spi_dev * spi, 186 232 int spi_freq , … … 205 251 } 206 252 207 /* 208 * vim: tabstop=4 : shiftwidth=4 : expandtab : softtabstop=4 209 */ 253 // Local Variables: 254 // tab-width: 4 255 // c-basic-offset: 4 256 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 257 // indent-tabs-mode: nil 258 // End: 259 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 -
branch/giet_vm_ioc_drivers/giet_drivers/spi_driver.h
r283 r284 1 /** 2 * \file : spi_driver.h 3 * \date : 30 August 2012 4 * \author: Cesar Fuguet <cesar.fuguet-tortolero@lip6.fr> 5 * 6 * This file contains the definition of a driver for the SPI controller 7 */ 8 9 #ifndef SPI_DRIVER_H 10 #define SPI_DRIVER_H 1 /////////////////////////////////////////////////////////////////////////////////// 2 // File : spi_driver.h 3 // Date : 31/08/2012 4 // Author : cesar fuguet 5 // Copyright (c) UPMC-LIP6 6 /////////////////////////////////////////////////////////////////////////////////// 7 #ifndef _GIET_SPI_DRIVER_H_ 8 #define _GIET_SPI_DRIVER_H_ 11 9 12 10 #include <io.h> 13 11 #include <mapping_info.h> 14 12 15 / **16 * SPI type definition17 */13 /////////////////////////////////////////////////////////////////////////////// 14 // SPI structure definition 15 /////////////////////////////////////////////////////////////////////////////// 18 16 struct spi_dev 19 17 { 20 /** 21 * RX/TX registers of the SPI controller 22 */ 18 // RX/TX registers of the SPI controller 23 19 unsigned int rx_tx[4]; 24 20 25 /** 26 * Control register of the SPI controller 27 */ 21 // control register of the SPI controller 28 22 unsigned int ctrl; 29 23 30 /** 31 * Divider register for the SPI controller generated clock signal 32 */ 24 // divider register for the SPI controller generated clock signal 33 25 unsigned int divider; 34 26 35 /** 36 * Slave select register of the SPI controller 37 */ 27 // slave select register of the SPI controller 38 28 unsigned int ss; 29 30 // SPI-DMA registers 39 31 unsigned int dma_base; 40 32 unsigned int dma_baseh; … … 42 34 }; 43 35 44 /**45 * \param spi : initialized pointer to a SPI controller.46 * \param byte : Byte to send to the SPI controller47 * \param index : index of the TX register in the SPI (TX[index])48 *49 * \return void50 *51 * \brief Send a byte to one of the tx buffer registers of the52 * SPI controller53 */54 36 void spi_put_tx(struct spi_dev * spi, unsigned char byte, int index); 55 37 56 /**57 * \param spi : initialized pointer to a SPI controller.58 * \param index : index of the RX register in the SPI (RX[index])59 *60 * \return byte from the RX[index] register61 *62 * \brief Get a byte from one of the rx buffer registers of the63 * SPI controller64 */65 38 inline volatile unsigned char spi_get_rx(struct spi_dev * spi, int index); 66 39 67 /**68 * \param spi : initialized pointer to a SPI controller.69 * \param buf : buffer to store data read70 * \param count : byte count to read71 *72 * \return void73 *74 * \brief get a data block from the SPI controller using 128bits75 * reads if possible76 */77 40 unsigned int spi_get_data(struct spi_dev * spi, paddr_t buffer, unsigned int count); 78 41 79 /**80 * \param spi : initialized pointer to a SPI controller.81 * \param index : index of the slave select signal to assert82 *83 * \return void84 *85 * \brief Set the index selected slave select signal (ss[index] <= '0')86 */87 42 inline void spi_ss_assert(struct spi_dev * spi, int index); 88 43 89 /**90 * \param spi : initialized pointer to a SPI controller.91 * \param index : index of the slave select signal to deassert92 *93 * \return void94 *95 * \brief Unset the index selected slave select signal (ss[index] <= '0')96 */97 44 inline void spi_ss_deassert(struct spi_dev * spi, int index); 98 45 99 /** 100 * \param spi : initialized pointer to a SPI controller. 101 * \param spi_freq : SPI Master to Slave clock frequency (in Hz) 102 * \param sys_freq : System clock frequency (in Hz) 103 * \param char_len : number to bits to transmit in one transfer 104 * \param tx_edge : when 0, the Master Out Slave In signal is changed 105 * on the falling edge of the clock 106 * \param rx_edge : when 0, the Master In Slave Out signal is latched 107 * on the falling edge of the clock 108 * 109 * \return void 110 * 111 * \brief Configure the SPI controller 112 * \note Any of the arguments can be less than 0 if you want to keep the old value 113 */ 114 void _spi_init ( 115 struct spi_dev * spi, 116 int spi_freq , 117 int sys_freq , 118 int char_len , 119 int tx_edge , 120 int rx_edge ); 46 void _spi_init ( struct spi_dev * spi, 47 int spi_freq , 48 int sys_freq , 49 int char_len , 50 int tx_edge , 51 int rx_edge ); 121 52 122 / **123 *SPI macros and constants124 */125 #define SPI_TX_POSEDGE 1 / **< MOSI is changed on neg edge */126 #define SPI_TX_NEGEDGE 0 / **< MOSI is changed on pos edge */127 #define SPI_RX_POSEDGE 1 / **< MISO is latched on pos edge */128 #define SPI_RX_NEGEDGE 0 / **< MISO is latched on neg edge */53 /////////////////////////////////////////////////////////////////////////////// 54 // SPI macros and constants 55 /////////////////////////////////////////////////////////////////////////////// 56 #define SPI_TX_POSEDGE 1 // MOSI is changed on neg edge 57 #define SPI_TX_NEGEDGE 0 // MOSI is changed on pos edge 58 #define SPI_RX_POSEDGE 1 // MISO is latched on pos edge 59 #define SPI_RX_NEGEDGE 0 // MISO is latched on neg edge 129 60 130 #define SPI_CTRL_ASS_EN ( 1 << 13 ) / **< Auto Slave Sel Assertion */131 #define SPI_CTRL_IE_EN ( 1 << 12 ) / **< Interrupt Enable */132 #define SPI_CTRL_LSB_EN ( 1 << 11 ) / **< LSB are sent first */133 #define SPI_CTRL_TXN_EN ( 1 << 10 ) / **< MOSI is changed on neg edge */134 #define SPI_CTRL_RXN_EN ( 1 << 9 ) / **< MISO is latched on neg edge */135 #define SPI_CTRL_GO_BSY ( 1 << 8 ) / **< Start the transfer */136 #define SPI_CTRL_DMA_BSY (1 << 16) /*** DMA in progress */137 #define SPI_CTRL_CHAR_LEN_MASK ( 0xFF ) / **< Bits transmited in 1 transfer */138 #define SPI_RXTX_MASK ( 0xFF ) / **< Mask for the an RX/TX value */61 #define SPI_CTRL_ASS_EN ( 1 << 13 ) // Auto Slave Sel Assertion 62 #define SPI_CTRL_IE_EN ( 1 << 12 ) // Interrupt Enable 63 #define SPI_CTRL_LSB_EN ( 1 << 11 ) // LSB are sent first 64 #define SPI_CTRL_TXN_EN ( 1 << 10 ) // MOSI is changed on neg edge 65 #define SPI_CTRL_RXN_EN ( 1 << 9 ) // MISO is latched on neg edge 66 #define SPI_CTRL_GO_BSY ( 1 << 8 ) // Start the transfer 67 #define SPI_CTRL_DMA_BSY ( 1 << 16 ) // DMA in progress 68 #define SPI_CTRL_CHAR_LEN_MASK ( 0xFF ) // Bits transmited in 1 transfer 69 #define SPI_RXTX_MASK ( 0xFF ) // Mask for the an RX/TX value 139 70 140 #define SPI_DMA_COUNT_READ (1 << 0) /* operation is a read (else write) */71 #define SPI_DMA_COUNT_READ ( 1 << 0 ) // operation is a read (else write) 141 72 142 /** 143 * \param x : Initialized pointer to the SPI controller 144 * 145 * \return 1 if there is an unfinished transfer in the SPI controller 146 * 147 * \brief Check the GO_BUSY bit of the SPI Controller 148 */ 149 #define SPI_IS_BUSY(x) ((ioread32(&x->ctrl) & (SPI_CTRL_GO_BSY|SPI_CTRL_DMA_BSY)) != 0) ? 1 : 0 73 /////////////////////////////////////////////////////////////////////////////// 74 // SPI_IS_BUSY() 75 // This macro checks the GO_BSY and DMA_BSY bits of the SPI controller which 76 // indicates an ongoing transfer. 77 // 78 // Returns 1 if there is an unfinished transfer 79 /////////////////////////////////////////////////////////////////////////////// 80 #define SPI_IS_BUSY(x) \ 81 ((ioread32(&x->ctrl) & (SPI_CTRL_GO_BSY|SPI_CTRL_DMA_BSY)) != 0) ? 1 : 0 150 82 151 83 #endif 152 84 153 /* 154 * vim: tabstop=4 : shiftwidth=4 : expandtab : softtabstop=4 155 */ 85 // Local Variables: 86 // tab-width: 4 87 // c-basic-offset: 4 88 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 89 // indent-tabs-mode: nil 90 // End: 91 // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Note: See TracChangeset
for help on using the changeset viewer.