mirror of
https://github.com/laanwj/k210-sdk-stuff.git
synced 2024-11-22 09:26:21 +04:00
rust: sdlcd improvements
- Init error reporting - Put 16-bit halves of display output correctly - Better comments
This commit is contained in:
parent
a46b314c6d
commit
ed91b43e2a
@ -1,4 +1,4 @@
|
||||
//! SD card slot access on Maix Go
|
||||
//! SD card slot access (in SPI mode) on Maix Go
|
||||
// TODO: actually use the DMA channel that is claimed…
|
||||
use core::convert::TryInto;
|
||||
|
||||
@ -34,7 +34,7 @@ pub const SEC_LEN: usize = 512;
|
||||
/** SD commands */
|
||||
#[repr(u8)]
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
enum CMD {
|
||||
pub enum CMD {
|
||||
/** Software reset */
|
||||
CMD0 = 0,
|
||||
/** Check voltage range (SDC V2) */
|
||||
@ -67,6 +67,13 @@ enum CMD {
|
||||
CMD59 = 59,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum InitError {
|
||||
CMDFailed(CMD, u8),
|
||||
CardCapacityStatusNotSet([u8; 4]),
|
||||
CannotGetCardInfo,
|
||||
}
|
||||
|
||||
/**
|
||||
* Card Specific Data: CSD Register
|
||||
*/
|
||||
@ -441,15 +448,18 @@ impl<'a, X: SPI> SDCard<'a, X> {
|
||||
}
|
||||
|
||||
/*
|
||||
* Initializes the SD/SD communication.
|
||||
* Initializes the SD/SD communication in SPI mode.
|
||||
* @param None
|
||||
* @retval The SD Response info if succeeeded, otherwise Err
|
||||
*/
|
||||
pub fn init(&self) -> Result<SD_CardInfo, ()> {
|
||||
pub fn init(&self) -> Result<SD_CardInfo, InitError> {
|
||||
/* Initialize SD_SPI */
|
||||
self.lowlevel_init();
|
||||
/* SD chip select high */
|
||||
self.CS_HIGH();
|
||||
/* NOTE: this reset doesn't always seem to work if the SD access was broken off in the
|
||||
* middle of an operation: CMDFailed(CMD0, 127). */
|
||||
|
||||
/* Send dummy byte 0xFF, 10 times with CS high */
|
||||
/* Rise CS and MOSI for 80 clocks cycles */
|
||||
/* Send dummy byte 0xFF */
|
||||
@ -457,15 +467,15 @@ impl<'a, X: SPI> SDCard<'a, X> {
|
||||
/*------------Put SD in SPI mode--------------*/
|
||||
/* SD initialized and set to SPI mode properly */
|
||||
|
||||
/* Send software reset */
|
||||
self.send_cmd(CMD::CMD0, 0, 0x95);
|
||||
let result = self.get_response();
|
||||
self.end_cmd();
|
||||
if result != 0x01 {
|
||||
// printf("SD_CMD0 is %X\n", result);
|
||||
// TODO: better erroring
|
||||
return Err(());
|
||||
return Err(InitError::CMDFailed(CMD::CMD0, result));
|
||||
}
|
||||
|
||||
/* Check voltage range */
|
||||
self.send_cmd(CMD::CMD8, 0x01AA, 0x87);
|
||||
/* 0x01 or 0x05 */
|
||||
let result = self.get_response();
|
||||
@ -473,17 +483,18 @@ impl<'a, X: SPI> SDCard<'a, X> {
|
||||
self.read_data(&mut frame);
|
||||
self.end_cmd();
|
||||
if result != 0x01 {
|
||||
//printf("SD_CMD8 is %X\n", result);
|
||||
return Err(());
|
||||
return Err(InitError::CMDFailed(CMD::CMD8, result));
|
||||
}
|
||||
let mut index = 255;
|
||||
while index != 0 {
|
||||
/* <ACMD> */
|
||||
self.send_cmd(CMD::CMD55, 0, 0);
|
||||
let result = self.get_response();
|
||||
self.end_cmd();
|
||||
if result != 0x01 {
|
||||
return Err(());
|
||||
return Err(InitError::CMDFailed(CMD::CMD55, result));
|
||||
}
|
||||
/* Initiate SDC initialization process */
|
||||
self.send_cmd(CMD::ACMD41, 0x40000000, 0);
|
||||
let result = self.get_response();
|
||||
self.end_cmd();
|
||||
@ -493,12 +504,12 @@ impl<'a, X: SPI> SDCard<'a, X> {
|
||||
index -= 1;
|
||||
}
|
||||
if index == 0 {
|
||||
//printf("SD_CMD55 is %X\n", result);
|
||||
return Err(());
|
||||
return Err(InitError::CMDFailed(CMD::ACMD41, result));
|
||||
}
|
||||
index = 255;
|
||||
let mut frame = [0u8; 4];
|
||||
while index != 0 {
|
||||
/* Read OCR */
|
||||
self.send_cmd(CMD::CMD58, 0, 1);
|
||||
let result = self.get_response();
|
||||
self.read_data(&mut frame);
|
||||
@ -509,20 +520,19 @@ impl<'a, X: SPI> SDCard<'a, X> {
|
||||
index -= 1;
|
||||
}
|
||||
if index == 0 {
|
||||
// printf("SD_CMD58 is %X\n", result);
|
||||
return Err(());
|
||||
return Err(InitError::CMDFailed(CMD::CMD58, result));
|
||||
}
|
||||
if (frame[0] & 0x40) == 0 {
|
||||
return Err(());
|
||||
return Err(InitError::CardCapacityStatusNotSet(frame));
|
||||
}
|
||||
self.HIGH_SPEED_ENABLE();
|
||||
self.get_cardinfo()
|
||||
.map_err(|_| InitError::CannotGetCardInfo)
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads a block of data from the SD.
|
||||
* @param data_buf: pointer to the buffer that receives the data read from the
|
||||
* SD.
|
||||
* @param data_buf: slice that receives the data read from the SD.
|
||||
* @param sector: SD's internal address to read from.
|
||||
* @retval The SD Response:
|
||||
* - `Err(())`: Sequence failed
|
||||
@ -572,8 +582,7 @@ impl<'a, X: SPI> SDCard<'a, X> {
|
||||
|
||||
/*
|
||||
* Writes a block to the SD
|
||||
* @param data_buf: pointer to the buffer containing the data to be written on
|
||||
* the SD.
|
||||
* @param data_buf: slice containing the data to be written to the SD.
|
||||
* @param sector: address to write on.
|
||||
* @retval The SD Response:
|
||||
* - `Err(())`: Sequence failed
|
||||
|
@ -1,4 +1,6 @@
|
||||
/*! Stream raw data from SD card to LCD, bascially a test for using both SPI0 and SPI1 */
|
||||
/*! Stream raw data from SD card to LCD, bascially a test for using both SPI0 and SPI1
|
||||
* at the same time
|
||||
*/
|
||||
#![allow(dead_code)]
|
||||
#![allow(non_snake_case)]
|
||||
#![allow(non_camel_case_types)]
|
||||
@ -9,8 +11,8 @@ use core::convert::TryInto;
|
||||
use k210_hal::prelude::*;
|
||||
use k210_hal::stdout::Stdout;
|
||||
use k210_hal::Peripherals;
|
||||
use k210_shared::board::def::{io,DISP_WIDTH,DISP_HEIGHT,DISP_PIXELS};
|
||||
use k210_shared::board::lcd::{LCD,LCDHL,self};
|
||||
use k210_shared::board::def::{io, DISP_HEIGHT, DISP_PIXELS, DISP_WIDTH};
|
||||
use k210_shared::board::lcd::{self, LCD, LCDHL};
|
||||
use k210_shared::board::lcd_colors;
|
||||
use k210_shared::board::sdcard;
|
||||
use k210_shared::soc::dmac::{dma_channel, DMACExt};
|
||||
@ -22,7 +24,7 @@ use riscv_rt::entry;
|
||||
|
||||
/** GPIOHS GPIO number to use for controlling the SD card CS pin */
|
||||
const SD_CS_GPIONUM: u8 = 7;
|
||||
/** CS value passed to SPI controller, this is a dummy value as SPI0_CS3 is not mapping to anything
|
||||
/** CS value passed to SPI controller, this is a dummy value as SPI0_CS3 is not mapped to anything
|
||||
* in the FPIOA */
|
||||
const SD_CS: u32 = 3;
|
||||
|
||||
@ -90,14 +92,17 @@ fn main() -> ! {
|
||||
let mut image: ScreenImage = [0; DISP_PIXELS / 2];
|
||||
let mut buffer = [0u8; DISP_PIXELS * 2];
|
||||
while sector < num_sectors {
|
||||
sd.read_sector(&mut buffer, sector.try_into().unwrap()).unwrap();
|
||||
/* Read raw image */
|
||||
sd.read_sector(&mut buffer, sector.try_into().unwrap())
|
||||
.unwrap();
|
||||
writeln!(stdout, "sector {} succesfully read", sector).unwrap();
|
||||
let mut i = buffer.iter();
|
||||
/* Combine into u32s, reordering 16-bit halves */
|
||||
for x in image.iter_mut() {
|
||||
*x = (u32::from(*i.next().unwrap()) << 0) |
|
||||
(u32::from(*i.next().unwrap()) << 8) |
|
||||
(u32::from(*i.next().unwrap()) << 16) |
|
||||
(u32::from(*i.next().unwrap()) << 24);
|
||||
*x = (u32::from(*i.next().unwrap()) << 16)
|
||||
| (u32::from(*i.next().unwrap()) << 24)
|
||||
| (u32::from(*i.next().unwrap()) << 0)
|
||||
| (u32::from(*i.next().unwrap()) << 8);
|
||||
}
|
||||
lcd.draw_picture(0, 0, DISP_WIDTH, DISP_HEIGHT, &image);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user