Removing USB

Need to refine the drive to the iron tip
This commit is contained in:
Ben V. Brown
2016-09-16 19:23:29 +10:00
parent 278d29bf4c
commit 1ec2477033
45 changed files with 72 additions and 6782 deletions

View File

@@ -1,284 +0,0 @@
/********************* (C) COPYRIGHT 2015 e-Design Co.,Ltd. ********************
File Name : 2FAT12.c
Version : S100 APP Ver 2.11
Description:
Author : bure & Celery
Data: 2015/08/03
History:
2016/09/13 Ben V. Brown -> English comments and cleaning up
2015/08/03
*******************************************************************************/
#include <string.h>
#include "FAT12.h"
#include "Bios.h"
#define FAT_LEN 0x1800
#define FAT1_BASE 0x00001000 // FAT1
#define FAT2_BASE 0x00002800 // FAT2
#define ROOT_BASE 0x00004000 //
#define FILE_BASE 0x00008000 //
#define SEC_LEN 512 //length of a sector -> 512 Bytes
#define FAT1_SEC 0x0C // FAT1 Sector
#define FAT2_SEC 0x0C // FAT2 Sector
#define OK 0 //Error codes
#define SEC_ERR 1 //
#define FAT_ERR 2 //
#define OVER 3 //
#define NEW 4 //
#define END 0xFFF //
#define OW 0 //
#define RW 1 //
/*******************************************************************************
Function: NextCluster
Description:
Input:
*******************************************************************************/
u8 NextCluster(u16* pCluster) {
u16 FatNum;
u32 Addr = FAT1_BASE + (*pCluster + *pCluster / 2);
*(pCluster + 1) = *pCluster; // <20><><EFBFBD><EFBFBD>ǰһ<C7B0><D2BB><EFBFBD>غ<EFBFBD>
// *(pCluster+1)= 0;
if ((*pCluster >= END) || (*pCluster < 2))
return OK;
if (ReadDiskData((u8*) &FatNum, Addr, 2) != OK)
return SEC_ERR;
*pCluster = (*pCluster & 1) ? (FatNum >> 4) : (FatNum & 0x0FFF); // ָ<><D6B8><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>غ<EFBFBD>
return OK;
}
/*******************************************************************************
Function: ReadFileSec
Description:
Input:
*******************************************************************************/
u8 ReadFileSec(u8* pBuffer, u16* pCluster) {
u32 ReadAddr = FILE_BASE + SEC_LEN * (*pCluster - 2);
//This code appears to read the data in two chunks of 256 bytes...
if (ReadDiskData(pBuffer, ReadAddr, 256) != OK)
return SEC_ERR; //
pBuffer += 256;
ReadAddr += 256;
if (ReadDiskData(pBuffer, ReadAddr, 256) != OK)
return SEC_ERR; // Failed to read the sector
if (NextCluster(pCluster) != 0)
return FAT_ERR; //
return OK;
}
/*******************************************************************************
Function: ProgFileSec
Description:
Input:
*******************************************************************************/
u8 ProgFileSec(u8* pBuffer, u16* pCluster) {
u16 Tmp;
u32 ProgAddr = FILE_BASE + SEC_LEN * (*pCluster - 2);
if (ProgDiskPage(pBuffer, ProgAddr) != OK)
return SEC_ERR; //
pBuffer += 256;
ProgAddr += 256;
if (ProgDiskPage(pBuffer, ProgAddr) != OK)
return SEC_ERR; //
Tmp = *pCluster;
switch (Tmp) {
case 0:
case 1:
if (SeekBlank(pBuffer, pCluster) != OK)
return OVER;
if (SetCluster(pBuffer, pCluster) != OK)
return SEC_ERR;
*(pCluster + 1) = Tmp;
return OK;
case END:
default:
if (NextCluster(pCluster) != OK)
return FAT_ERR;
return OK;
}
}
/*******************************************************************************
Function: SeekBlank
Description:
Input:
*******************************************************************************/
u8 SeekBlank(u8* pBuffer, u16* pCluster) {
u16 Offset, Tmp, i, n = 0;
u32 SecAddr;
for (i = 0; i < 4096; i++) {
Offset = i + i / 2;
if ((Offset % 256) == 0) {
SecAddr = FAT1_BASE + (Offset & (~0xFF));
if (ReadDiskData(pBuffer, SecAddr, 258) != 0)
return SEC_ERR;
}
Offset %= 256;
Tmp = pBuffer[Offset] + (pBuffer[Offset + 1] << 8);
Tmp = (i & 1) ? (Tmp >> 4) : (Tmp & 0xFFF);
if (Tmp == 0) {
*pCluster++ = i;
n++;
if (n > 1)
return OK;
}
}
*(pCluster + 1) = 0xFFF;
return OK;
}
/*******************************************************************************
Function:
Description:
Input:
*******************************************************************************/
u8 SetCluster(u8* pBuffer, u16* pCluster) {
u16 Offset, Tmp, i, k;
u32 SecAddr;
i = *pCluster; // <20><>ȡԭ<C8A1><D4AD>ǰ<EFBFBD>غ<EFBFBD>
k = *(pCluster + 1); // <20><>ȡ<EFBFBD><C8A1>һ<EFBFBD>غ<EFBFBD>
*pCluster = k;
Offset = i + i / 2;
SecAddr = FAT1_BASE + (Offset & (~0xFF));
Tmp = Offset & 0xFF;
if (ReadDiskData(pBuffer, SecAddr, 256) != 0)
return SEC_ERR;
if (i & 1)
pBuffer[Tmp] = ((k << 4) & 0xF0) + (pBuffer[Tmp] & 0x0F);
else
pBuffer[Tmp] = k;
if (Tmp++ < 256) {
if (i & 1)
pBuffer[Tmp] = k >> 4;
else
pBuffer[Tmp] = ((k >> 8) & 0x0F) + (pBuffer[Tmp] & 0xF0);
if (ProgDiskPage(pBuffer, SecAddr) != 0)
return SEC_ERR;
} else {
if (ProgDiskPage(pBuffer, SecAddr) != 0)
return SEC_ERR;
SecAddr += 256;
if (ReadDiskData(pBuffer, SecAddr, 256) != 0)
return SEC_ERR;
if (i & 1)
pBuffer[0] = k >> 4;
else
pBuffer[0] = ((k >> 8) & 0x0F) + (pBuffer[0] & 0xF0);
if (ProgDiskPage(pBuffer, SecAddr) != 0)
return SEC_ERR;
}
return OK;
}
/*******************************************************************************
Function:
Description:
Input:
*******************************************************************************/
u8 FAT_SearchFile(u8* pBuffer, u8* pFileName, u16* pCluster, u32* pDirAddr,
u32* flag) {
u16 i, n;
*pCluster = 0;
for (*pDirAddr = ROOT_BASE; *pDirAddr < FILE_BASE;) {
if (ReadDiskData(pBuffer, *pDirAddr, 256) != OK)
return SEC_ERR;
for (n = 0; n < 256; n += 32) {
for (i = 0; i < 4; i++) {
if (pBuffer[n + i] != 0) {
if (pBuffer[n + i] != pFileName[i])
break;
if (i == 3) { // <20>ҵ<EFBFBD><D2B5>ļ<EFBFBD><C4BC><EFBFBD>
*pCluster = *(u16*) (pBuffer + n + 0x1A); // <20>ļ<EFBFBD><C4BC><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>غ<EFBFBD>
return OK;
}
} else
return NEW; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>հ<EFBFBD>Ŀ¼<C4BF><C2BC>󷵻<EFBFBD>
}
*pDirAddr += 32;
}
}
return OVER;
}
/*******************************************************************************
Function:OpenFileRd
Description: Opens a file for reading from
Input:
*******************************************************************************/
u8 OpenFileRd(u8* pBuffer, u8* pFileName, u16* pCluster, u32* pDirAddr) {
u16 i, n;
*pCluster = 0;
for (*pDirAddr = ROOT_BASE; *pDirAddr < FILE_BASE;) {
if (ReadDiskData(pBuffer, *pDirAddr, 256) != OK)
return SEC_ERR;
for (n = 0; n < 256; n += 32) {
for (i = 0; i < 11; i++) {
if (pBuffer[n + i] != 0) {
if (pBuffer[n + i] != pFileName[i])
break;
if (i == 10) { // <20>ҵ<EFBFBD><D2B5>ļ<EFBFBD><C4BC><EFBFBD>
*pCluster = *(u16*) (pBuffer + n + 0x1A); // <20>ļ<EFBFBD><C4BC><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>غ<EFBFBD>
return OK;
}
} else
return NEW; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>հ<EFBFBD>Ŀ¼<C4BF><C2BC>󷵻<EFBFBD>
}
*pDirAddr += 32;
}
}
return OVER;
}
/*******************************************************************************
Function: OpenFileWr
Description: Opens a file for writing to
Input:
*******************************************************************************/
u8 OpenFileWr(u8* pBuffer, u8* pFileName, u16* pCluster, u32* pDirAddr) {
u16 i, n;
i = OpenFileRd(pBuffer, pFileName, pCluster, pDirAddr);
if (i != NEW)
return i;
else { // <20><>ǰ<EFBFBD><C7B0>Ϊ<EFBFBD>հ<EFBFBD>Ŀ¼<C4BF><C2BC>
if (SeekBlank(pBuffer, pCluster) != OK)
return OVER; // <20><>FAT<41><54><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
n = *pDirAddr & 0xFF; // nΪ<6E><CEAA>ǰҳĿ¼<C4BF><C2BC>
if (ReadDiskData(pBuffer, (*pDirAddr) - n, 256) != OK)
return SEC_ERR;
for (i = 0; i < 11; i++)
pBuffer[n + i] = pFileName[i]; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ¼<C4BF><C2BC>
*(u16*) (pBuffer + n + 0x1A) = *pCluster;
if (ProgDiskPage(pBuffer, (*pDirAddr) - n) != OK)
return SEC_ERR;
return OK;
}
}
/*******************************************************************************
Function: CloseFile
Description: Closes a file that was previously opened
Input:
*******************************************************************************/
u8 CloseFile(u8* pBuffer, u32 Lenght, u16* pCluster, u32* pDirAddr) {
u16 n;
// *pCluster = *(pCluster+1); // <20><>ȡǰһ<C7B0><D2BB><EFBFBD>غ<EFBFBD>
*(pCluster + 1) = 0xFFF;
SetCluster(pBuffer, pCluster);
if (ReadDiskData(pBuffer, (*pDirAddr & (~0xFF)), 256) != OK)
return SEC_ERR;
*(u8*) (pBuffer + (*pDirAddr & 0xFF) + 0x0B) = 0x20;
*(u32*) (pBuffer + (*pDirAddr & 0xFF) + 0x1C) = Lenght;
if (ProgDiskPage(pBuffer, (*pDirAddr & (~0xFF))) != OK)
return SEC_ERR;
for (n = 0; n < FAT1_SEC; n++) {
if (ReadDiskData(pBuffer, FAT1_BASE + n * 256, 256) != OK)
return SEC_ERR;
if (ProgDiskPage(pBuffer, FAT2_BASE + n * 256) != OK)
return SEC_ERR;
}
return OK;
}
/******************************** END OF FILE *********************************/

View File

@@ -9,7 +9,7 @@
*******************************************************************************/
#include <Hardware.h>
#include <usb_lib.h>
#include "APP_Version.h"
#include "Bios.h"
#include "I2C.h"
@@ -52,8 +52,8 @@ u32 Get_HeatingTime(void) {
return gHeat_cnt;
}
/*******************************************************************************
Function:
Description: Init the global count down timers
Function:
Description: Init the global count down timers
*******************************************************************************/
void Init_Gtime(void) {
u8 i;
@@ -85,22 +85,6 @@ void Delay_HalfMs(u32 ms) {
; // {if(Scan_key()!=0)break;}
}
/*******************************************************************************
Function: USB_Port
Description: Enables or disables the usb pins
Input: state == ENABLE or DISABLE
*******************************************************************************/
void USB_Port(u8 state) {
USB_DN_LOW();
USB_DP_LOW();
if (state == DISABLE) {
USB_DN_OUT();
USB_DP_OUT();
} else {
USB_DN_EN();
USB_DP_EN();
}
}
/*******************************************************************************
Function:RCC_Config
Description:Setup the system clocks to use internal HSE to run the system at 48Mhz
@@ -123,11 +107,9 @@ void RCC_Config(void) {
RCC_AHBPeriphClockCmd(
RCC_AHBPeriph_SRAM | RCC_AHBPeriph_DMA1 | RCC_AHBPeriph_DMA2 |
RCC_AHBPeriph_FLITF, // Enable DMA1 clock ???
ENABLE);
RCC_AHBPeriph_FLITF, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |
RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2, //| RCC_APB2Periph_ADC3, //RCC_APB2Periph_TIM1,
ENABLE);
RCC_APB2Periph_ADC1 | RCC_APB2Periph_ADC2, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2 | RCC_APB1Periph_TIM3, ENABLE);
RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_Div1); // USBCLK = 48MHz
@@ -145,8 +127,9 @@ void NVIC_Config(u16 tab_offset) {
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
NVIC_Init(&NVIC_InitStructure);
}
/*******************************************************************************
Function:GPIO_Config
@@ -178,7 +161,7 @@ void GPIO_Config(void) {
GPIO_InitStructure.GPIO_Pin = OLED_RST_PIN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_Init(GPIOA, &GPIO_InitStructure);
//------- Heat_Pin - Iron enable output PB4--------------------------------------------------------//
GPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST, ENABLE); //Disable PB4=JNTRST
@@ -301,8 +284,10 @@ void Init_Timer2(void) {
NVIC_Init(&NVIC_InitStructure);
}
/*******************************************************************************
Function:
Description: Init Timer3 to fire every 50us to be used to control the irons software PWM
Function:
Description: Init Timer3 to fire every 50us to be used to control the irons software PWM
This needs to be really fast as there is a cap used between this and the driver circuitry
That prevents astuck mcu heating the tip
*******************************************************************************/
void Init_Timer3(void) {
NVIC_InitTypeDef NVIC_InitStructure;
@@ -332,7 +317,7 @@ void Init_Timer3(void) {
Also reads the buttons every 4 ticks
*******************************************************************************/
void TIM2_ISR(void) {
static u8 buttonReadDivider;
volatile static u8 buttonReadDivider;
TIM_ClearITPendingBit(TIM2, TIM_IT_Update); // Clear interrupt flag
for (u8 i = 0; i < 8; i++)
@@ -348,27 +333,24 @@ void TIM2_ISR(void) {
If the Heat_cnt >0 then heater on, otherwise off.
*******************************************************************************/
void TIM3_ISR(void) {
volatile static u8 heat_flag = 0;
volatile static u8 heat_flag = 0; //heat flag == used to make the pin toggle
TIM_ClearITPendingBit(TIM3, TIM_IT_Update); // Clear interrupt flag
if (gTimeOut > 0)
gTimeOut--;
if (gMs_timeout > 0)
gMs_timeout--;
if (gHeat_cnt > 0) {
gHeat_cnt--;
--gHeat_cnt;
if (heat_flag)
HEAT_OFF();
else
HEAT_ON();
heat_flag = ~heat_flag;
}
if (gHeat_cnt == 0) {
heat_flag = !heat_flag;
} else {
HEAT_OFF();
heat_flag = 0;
}
}
/******************************** END OF FILE *********************************/

View File

@@ -15,7 +15,6 @@
#include "UI.h"
#include "Hardware.h"
#include "S100V0_1.h"
#include "Disk.h"
#include "MMA8652FC.h"
#define HEATINGCYCLE 30
@@ -32,8 +31,8 @@ u8 gIs_restartkey = 0; //
u8 gPre_status = 1; //
const DEVICE_INFO_SYS info_def = { "2.13", //Ver
2000, //T_Standby; // 200C=1800 2520
3000, // T_Work; // 350C=3362,
1000, //T_Standby; // 200C=1800 2520
1000, // T_Work; // 350C=3362,
100, //T_Step;
3 * 60 * 100, //Wait_Time; //3*60*100 3 minutes
6 * 60 * 100 // Idle_Time; //6*60*100 6 minutes
@@ -43,7 +42,7 @@ struct _pid {
s16 actualtemp; //Actual current temp of the tip
s16 err; //Error term
s16 err_last; //last error term
s32 ht_time; //
u32 ht_time; //
u16 kp, ki, kd; //Constants for the PID Controller
s32 integral; //
} pid;
@@ -205,7 +204,7 @@ u32 Heating_Time(s16 temp, s16 wk_temp) {
*******************************************************************************/
void Status_Tran(void) //
{
static u16 init_waitingtime = 0; //<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>־λ: 0=> δ<><CEB4>ʼ<EFBFBD><CABC>,1=><3E>ѳ<EFBFBD>ʼ<EFBFBD><CABC>
static u16 init_waitingtime = 0;
static u8 back_prestatus = 0;
s16 heat_timecnt = 0, wk_temp;
u16 mma_active;
@@ -373,10 +372,9 @@ void Status_Tran(void) //
case TEMP_SET: //We are in the setting soldering iron temp mode
if(EFFECTIVE_KEY_TIMER == 0) {
gCalib_flag = 1;
Disk_BuffInit();
Config_Analysis(); //
gCalib_flag = 0;
Set_CtrlStatus(TEMP_CTR);//return to soldering mode
Set_CtrlStatus(TEMP_CTR); //return to soldering mode
TEMPSHOW_TIMER = 0;//turn off the timer
}
break;
@@ -395,8 +393,6 @@ void Status_Tran(void) //
case KEY_CN|KEY_V3:
Zero_Calibration(); //Calibrate the temperature (i think??)
if(Get_CalFlag() == 1) {
Disk_BuffInit();
Config_Analysis(); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>U<EFBFBD><55>
}
KD_TIMER = 200; //20150717 <20>޸<EFBFBD>
break;
@@ -436,11 +432,6 @@ void Status_Tran(void) //
}
break;
}
//V-- No idea what this does yet.. At all.. since it will always be skipped..
if(Get_HeatingTime != 0) {
Set_HeatingTime(0); //<2F><><EFBFBD><EFBFBD>ֹͣ<CDA3><D6B9><EFBFBD><EFBFBD>
HEAT_OFF();
}
break;
default:
break;

View File

@@ -1,773 +0,0 @@
/********************* (C) COPYRIGHT 2015 e-Design Co.,Ltd. **********************
File Name : Disk.c
Version : S100 APP Ver 2.11
Description:
Author : Celery
Data: 2015/07/07
History:
2016/09/13 Ben V. Brown English notation/comments
2015/07/07
*******************************************************************************/
#include <string.h>
#include <stdio.h>
#include "APP_Version.h"
#include "Disk.h"
#include "Bios.h"
#include "Flash.h"
#include "Oled.h"
#include "UI.h"
#include "CTRL.h"
#include "Hardware.h"
#define Delay_mS Delay_Ms
void Disk_SecWrite(u8* pBuffer, u32 DiskAddr);
void Disk_SecRead(u8* pBuffer, u32 DiskAddr);
void Soft_Delay(void);
//Hard coded boot sector for the virtual device
const uint8_t BOOT_SEC[512] = { 0xEB, 0x3C, 0x90, 0x4D, 0x53, 0x44, 0x4F, 0x53,
0x35, 0x2E, 0x30, 0x00, 0x02, 0x01, 0x08, 0x00, 0x02, 0x00, 0x02, 0x50,
0x00, 0xF8, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x29, 0xA2, 0x98, 0xE4, 0x6C, 0x4E,
0x4F, 0x20, 0x4E, 0x41, 0x4D, 0x45, 0x20, 0x20, 0x20, 0x20, 0x46, 0x41,
0x54, 0x31, 0x32, 0x20, 0x20, 0x20, 0x33, 0xC9, 0x8E, 0xD1, 0xBC, 0xF0,
0x7B, 0x8E, 0xD9, 0xB8, 0x00, 0x20, 0x8E, 0xC0, 0xFC, 0xBD, 0x00, 0x7C,
0x38, 0x4E, 0x24, 0x7D, 0x24, 0x8B, 0xC1, 0x99, 0xE8, 0x3C, 0x01, 0x72,
0x1C, 0x83, 0xEB, 0x3A, 0x66, 0xA1, 0x1C, 0x7C, 0x26, 0x66, 0x3B, 0x07,
0x26, 0x8A, 0x57, 0xFC, 0x75, 0x06, 0x80, 0xCA, 0x02, 0x88, 0x56, 0x02,
0x80, 0xC3, 0x10, 0x73, 0xEB, 0x33, 0xC9, 0x8A, 0x46, 0x10, 0x98, 0xF7,
0x66, 0x16, 0x03, 0x46, 0x1C, 0x13, 0x56, 0x1E, 0x03, 0x46, 0x0E, 0x13,
0xD1, 0x8B, 0x76, 0x11, 0x60, 0x89, 0x46, 0xFC, 0x89, 0x56, 0xFE, 0xB8,
0x20, 0x00, 0xF7, 0xE6, 0x8B, 0x5E, 0x0B, 0x03, 0xC3, 0x48, 0xF7, 0xF3,
0x01, 0x46, 0xFC, 0x11, 0x4E, 0xFE, 0x61, 0xBF, 0x00, 0x00, 0xE8, 0xE6,
0x00, 0x72, 0x39, 0x26, 0x38, 0x2D, 0x74, 0x17, 0x60, 0xB1, 0x0B, 0xBE,
0xA1, 0x7D, 0xF3, 0xA6, 0x61, 0x74, 0x32, 0x4E, 0x74, 0x09, 0x83, 0xC7,
0x20, 0x3B, 0xFB, 0x72, 0xE6, 0xEB, 0xDC, 0xA0, 0xFB, 0x7D, 0xB4, 0x7D,
0x8B, 0xF0, 0xAC, 0x98, 0x40, 0x74, 0x0C, 0x48, 0x74, 0x13, 0xB4, 0x0E,
0xBB, 0x07, 0x00, 0xCD, 0x10, 0xEB, 0xEF, 0xA0, 0xFD, 0x7D, 0xEB, 0xE6,
0xA0, 0xFC, 0x7D, 0xEB, 0xE1, 0xCD, 0x16, 0xCD, 0x19, 0x26, 0x8B, 0x55,
0x1A, 0x52, 0xB0, 0x01, 0xBB, 0x00, 0x00, 0xE8, 0x3B, 0x00, 0x72, 0xE8,
0x5B, 0x8A, 0x56, 0x24, 0xBE, 0x0B, 0x7C, 0x8B, 0xFC, 0xC7, 0x46, 0xF0,
0x3D, 0x7D, 0xC7, 0x46, 0xF4, 0x29, 0x7D, 0x8C, 0xD9, 0x89, 0x4E, 0xF2,
0x89, 0x4E, 0xF6, 0xC6, 0x06, 0x96, 0x7D, 0xCB, 0xEA, 0x03, 0x00, 0x00,
0x20, 0x0F, 0xB6, 0xC8, 0x66, 0x8B, 0x46, 0xF8, 0x66, 0x03, 0x46, 0x1C,
0x66, 0x8B, 0xD0, 0x66, 0xC1, 0xEA, 0x10, 0xEB, 0x5E, 0x0F, 0xB6, 0xC8,
0x4A, 0x4A, 0x8A, 0x46, 0x0D, 0x32, 0xE4, 0xF7, 0xE2, 0x03, 0x46, 0xFC,
0x13, 0x56, 0xFE, 0xEB, 0x4A, 0x52, 0x50, 0x06, 0x53, 0x6A, 0x01, 0x6A,
0x10, 0x91, 0x8B, 0x46, 0x18, 0x96, 0x92, 0x33, 0xD2, 0xF7, 0xF6, 0x91,
0xF7, 0xF6, 0x42, 0x87, 0xCA, 0xF7, 0x76, 0x1A, 0x8A, 0xF2, 0x8A, 0xE8,
0xC0, 0xCC, 0x02, 0x0A, 0xCC, 0xB8, 0x01, 0x02, 0x80, 0x7E, 0x02, 0x0E,
0x75, 0x04, 0xB4, 0x42, 0x8B, 0xF4, 0x8A, 0x56, 0x24, 0xCD, 0x13, 0x61,
0x61, 0x72, 0x0B, 0x40, 0x75, 0x01, 0x42, 0x03, 0x5E, 0x0B, 0x49, 0x75,
0x06, 0xF8, 0xC3, 0x41, 0xBB, 0x00, 0x00, 0x60, 0x66, 0x6A, 0x00, 0xEB,
0xB0, 0x4E, 0x54, 0x4C, 0x44, 0x52, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x0D, 0x0A, 0x52, 0x65, 0x6D, 0x6F, 0x76, 0x65, 0x20, 0x64, 0x69, 0x73,
0x6B, 0x73, 0x20, 0x6F, 0x72, 0x20, 0x6F, 0x74, 0x68, 0x65, 0x72, 0x20,
0x6D, 0x65, 0x64, 0x69, 0x61, 0x2E, 0xFF, 0x0D, 0x0A, 0x44, 0x69, 0x73,
0x6B, 0x20, 0x65, 0x72, 0x72, 0x6F, 0x72, 0xFF, 0x0D, 0x0A, 0x50, 0x72,
0x65, 0x73, 0x73, 0x20, 0x61, 0x6E, 0x79, 0x20, 0x6B, 0x65, 0x79, 0x20,
0x74, 0x6F, 0x20, 0x72, 0x65, 0x73, 0x74, 0x61, 0x72, 0x74, 0x0D, 0x0A,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAC, 0xCB, 0xD8, 0x55, 0xAA };
static u8 gDisk_buff[0x2600]; //RAM Buffer used to implement the virtual disk
static u32 gDisk_var[(512 + 32 + 28) / 4]; //
static u32 *gV32 = (u32*) &gDisk_var[512 / 4];
static u8 *gVar = (u8*) &gDisk_var[512 / 4 + 8];
static u8 *gBuff = (u8*) &gDisk_var[0];
const u8 gFat_data[] = { 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; //{0xF8,0XFF,0XFF,0xff,0X0f};//
//The options
const char *gKey_words[] = { "T_Standby", "T_Work", "Wait_Time", "Idle_Time",
"T_Step", "Turn_Off_v", "TempShowFlag", "ZeroP_Ad" };
//default settings
const char *gDef_set[] = { "T_Standby=200", "T_Work=300", "Wait_Time=180",
"Idle_Time=360", "T_Step=10", "Turn_Off_v=10", "TempShowFlag=0",
"ZeroP_Ad=239" };
//comments for accepted range
const char *gSet_range[] = { " #(100~400)\r\n", " #(100~400)\r\n",
" #(60~9999)\r\n", " #(300~9999)\r\n", " #(5~25)\r\n",
" #(9~12)\r\n", " #(0,1)\r\n", " #ReadOnly\r\n" };
static u8 gFile_con[512]; //file contents buffer
#define CONFIG_CONT 8 /*Number of variables in config.txt*/
u8 gRewriteflag[16]; //This flags if this sector has changed and needs to be written to flash
#define ROW_CONT 35
#define FILE_CONT 254
/*******************************************************************************
Function: Soft_Delay()
Description: Small software delay.
*******************************************************************************/
void Soft_Delay() {
int i, j;
for (i = 0; i < 1000; i++)
for (j = 0; j < 100; j++)
;
}
/*******************************************************************************
Function: Set_Ver
Description:
Input:
*******************************************************************************/
void Set_Ver(u8 str[], u8 k) {
s16 set_ver = 0;
switch (k) {
case 0:
set_ver = (str[0] - 48) * 100 + (str[1] - 48) * 10 + (str[2] - 48);
device_info.t_standby = set_ver * 10;
break;
case 1:
set_ver = (str[0] - 48) * 100 + (str[1] - 48) * 10 + (str[2] - 48);
if (!gCalib_flag)
device_info.t_work = set_ver * 10;
break;
case 2:
if (str[3] <= '9' && str[3] >= '0') { //4
set_ver = (str[0] - 48) * 1000 + (str[1] - 48) * 100
+ (str[2] - 48) * 10 + (str[3] - 48);
} else if (str[2] <= '9' && str[2] >= '0') { //3
set_ver = (str[0] - 48) * 100 + (str[1] - 48) * 10 + (str[2] - 48);
} else if (str[1] <= '9' && str[1] >= '0') { //2
set_ver = (str[0] - 48) * 10 + (str[1] - 48);
}
device_info.wait_time = set_ver * 100;
break;
case 3:
if (str[3] <= '9' && str[3] >= '0') { //4
set_ver = (str[0] - 48) * 1000 + (str[1] - 48) * 100
+ (str[2] - 48) * 10 + (str[3] - 48);
} else if (str[2] <= '9' && str[2] >= '0') { //3
set_ver = (str[0] - 48) * 100 + (str[1] - 48) * 10 + (str[2] - 48);
}
device_info.idle_time = set_ver * 100;
break;
case 4:
if (str[1] <= '9' && str[1] >= '0') { //2
set_ver = (str[0] - 48) * 10 + (str[1] - 48);
} else {
set_ver = str[0] - 48;
}
device_info.t_step = set_ver * 10;
break;
case 5:
if (str[3] <= '9' && str[3] >= '0') { //4
set_ver = (str[0] - 48) * 1000 + (str[1] - 48) * 100
+ (str[2] - 48) * 10 + (str[3] - 48);
} else if (str[2] <= '9' && str[2] >= '0') { //3
set_ver = (str[0] - 48) * 100 + (str[1] - 48) * 10 + (str[2] - 48);
} else if (str[1] <= '9' && str[1] >= '0') { //2
set_ver = (str[0] - 48) * 10 + (str[1] - 48);
} else {
set_ver = str[0] - 48;
}
gTurn_offv = set_ver * 10;
break;
case 6:
set_ver = str[0] - 48;
Set_TemperatureShowFlag(set_ver);
break;
case 7:
if (str[2] <= '9' && str[2] >= '0') { //3
set_ver = (str[0] - 48) * 100 + (str[1] - 48) * 10 + (str[2] - 48);
} else if (str[1] <= '9' && str[1] >= '0') { //2
set_ver = (str[0] - 48) * 10 + (str[1] - 48);
} else {
set_ver = str[0] - 48;
}
if (!gCalib_flag)
gZerop_ad = set_ver;
break;
default:
break;
}
}
/*******************************************************************************
Function: Cal_Val
Description:
Inputs:
Output:
*******************************************************************************/
u8 Cal_Val(u8 str[], u8 k, u8 flag) {
u16 set_ver;
switch (k) {
case 0:
case 1:
if (str[2] > '9' || str[2] < '0' || //
str[1] > '9' || str[1] < '0' || //
str[0] > '4' || str[0] <= '0' || //
(str[0] == '4' && (str[1] != '0' || str[2] != '0')))
return 0;
break;
case 2:
if (str[3] <= '9' && str[3] >= '0') { //
if ((str[2] > '9' && str[2] < '0')
|| (str[1] > '9' && str[1] < '0')) //
return 0;
} else if (str[2] <= '9' && str[2] >= '0') { //
if (str[1] > '9' && str[1] < '0') //
return 0;
} else if (str[1] <= '9' && str[1] >= '0') { //
if (str[0] > '9' || str[0] < '6') //
return 0;
} else {
return 0;
}
break;
case 3:
if (str[3] <= '9' && str[3] >= '0') { //4
if ((str[2] > '9' && str[2] < '0')
|| (str[1] > '9' && str[1] < '0')) //
return 0;
} else if (str[2] <= '9' && str[2] >= '0') { //3
if (str[0] > '9' || str[0] < '3') //
return 0;
} else { //
return 0;
}
break;
case 4: //T_Step=10 #(5~25)
if (str[1] <= '5' && str[1] >= '0') { //
if (str[0] > '2' || str[0] < '0') //
return 0;
} else {
if (str[0] < '5' && (str[0] != '1')) {
return 0;
}
}
break;
case 5: //Turn_Off_v=10 #(9~12)
if (str[1] <= '2' && str[1] >= '0') { //
if (str[0] > '9' || str[0] < '0') //
return 0;
} else {
if (str[0] < '9') {
return 0;
}
}
break;
case 6: //TempShowFlag=0 #(0,1)
if (str[0] != '1' && str[0] != '0')
return 0;
break;
case 7:
if (str[2] <= '9' && str[2] >= '0') { //3
set_ver = (str[0] - 48) * 100 + (str[1] - 48) * 10 + (str[2] - 48);
} else if (str[1] <= '9' && str[1] >= '0') { //2
set_ver = (str[0] - 48) * 10 + (str[1] - 48);
} else {
set_ver = str[0] - 48;
}
if (flag == 1) {
if (set_ver != gZerop_ad)
return 0;
}
break;
default:
break;
}
return 1;
}
/*******************************************************************************
Function:Disk_BuffInit
Description: Initializes the buffer for the virtual disk. By loading from the chips flash
*******************************************************************************/
void Disk_BuffInit(void) {
memcpy(gDisk_buff, (u8*) APP_BASE, 0x2600);
memset(gRewriteflag, 0, 16);
}
/*******************************************************************************
Function: Upper
Description: Converts the string passed in to upper case
Inputs: (str) buffer to change, (len) length of the buffer
*******************************************************************************/
void Upper(u8* str, u16 len) {
u16 i;
for (i = 0; i < len; i++) //Loop through the string
if (str[i] >= 'a' && str[i] <= 'z') //if char is lower case
str[i] -= 32; //shift to upper case
}
/*******************************************************************************
Function: SearchFile
Description:
Inputs: (pfilename) filename to look for, (pfilelen) length of the file,(root_addr) root folder to search from
Outputs: NULL (failed) or pointer to file start
*******************************************************************************/
u8* SearchFile(u8* pfilename, u16* pfilelen, u16* root_addr) {
u16 n, sector;
u8 str_name[11];
u8* pdiraddr;
pdiraddr = ROOT_SECTOR;
for (n = 0; n < 16; n++) {
memcpy(str_name, pdiraddr, 11);
Upper(str_name, 11); //ensure path is upper case
if (memcmp(str_name, pfilename, 11) == 0) {
memcpy((u8*) pfilelen, pdiraddr + 0x1C, 2);
memcpy((u8*) &sector, pdiraddr + 0x1A, 2);
return (u8*) FILE_SECTOR + (sector - 2) * 512;
}
pdiraddr += 32;
root_addr++;
}
return NULL;
}
/*******************************************************************************
Function:Config_Analysis
Description:Reads the CONFIG.TXT if file is found and also the LOGIN.BMP file as well
*******************************************************************************/
u8 Config_Analysis(void) {
u32 i, j, k, m, flag;
u16 file_len;
u8 t_p[CONFIG_CONT][ROW_CONT];
u8 str[FILE_CONT];
u8 is_illegality = 0;
u8* p_file;
u16 root_addr;
root_addr = 0;
m = 0;
j = 0;
//read in the config.txt if it exists
if ((p_file = SearchFile((u8*) ("CONFIG TXT"), &file_len, &root_addr))) {
memset(t_p, 0x00, CONFIG_CONT * ROW_CONT);
memcpy((u8*) gFile_con, p_file, 512);
for (k = 0; k < CONFIG_CONT; k++) {
j = 0;
for (i = m; i < strlen((char *) gFile_con); i++) {
if (gFile_con[i] == 0x0D && gFile_con[i + 1] == 0x0A)
break;
else {
if (j < ROW_CONT)
t_p[k][j++] = gFile_con[i];
m++;
}
}
t_p[k][j] = '\0';
m = i + 2;
}
for (k = 0; k < CONFIG_CONT; k++) {
if (memcmp(t_p[k], gKey_words[k], strlen(gKey_words[k])) == 0) {
flag = 0;
for (i = strlen(gKey_words[k]); i < strlen((char *) t_p[k]);
i++) {
if (t_p[k][i] >= '0' && t_p[k][i] <= '9') {
if (t_p[k][i] == '0') {
if (k == 6) {
flag = 1;
break;
} else {
flag = 0;
break;
}
}
flag = 1;
break;
} else if ((t_p[k][i] != 0x20) && (t_p[k][i] != 0x3d)) {
flag = 0;
break;
}
}
if (flag && Cal_Val(t_p[k] + i, k, 0)) {
Set_Ver(t_p[k] + i, k);
if (k == 0)
sprintf((char *) t_p[k], "T_Standby=%d",
device_info.t_standby / 10);
else if (k == 1)
sprintf((char *) t_p[k], "T_Work=%d",
device_info.t_work / 10);
else if (k == 2)
sprintf((char *) t_p[k], "Wait_Time=%ld",
device_info.wait_time / 100);
else if (k == 3)
sprintf((char *) t_p[k], "Idle_Time=%ld",
device_info.idle_time / 100);
else if (k == 4)
sprintf((char *) t_p[k], "T_Step=%d",
device_info.t_step / 10);
else if (k == 5)
sprintf((char *) t_p[k], "Turn_Off_v=%ld",
gTurn_offv / 10);
else if (k == 6)
sprintf((char *) t_p[k], "TempShowFlag=%d",
Get_TemperatureShowFlag());
else if (k == 7)
sprintf((char *) t_p[k], "ZeroP_Ad=%ld", gZerop_ad);
} else {
memset(t_p[k], 0, strlen((char *) t_p[k]));
memcpy(t_p[k], gDef_set[k], strlen((char *) gDef_set[k]));
is_illegality = 1;
}
} else {
memcpy(t_p[k], gDef_set[k], strlen((char *) gDef_set[k]));
is_illegality = 1;
}
}
if (is_illegality || gCalib_flag) {
memset(str, 0x00, FILE_CONT);
m = 0;
for (k = 0; k < CONFIG_CONT; k++) {
strcat((char *) str, (char *) t_p[k]);
strcat((char *) str, (char *) gSet_range[k]);
}
m = strlen((char *) str);
if (m < 256) {
gDisk_buff[0x400 + root_addr * 32 + 0x1C] = m; //strlen((char *)str);
gDisk_buff[0x400 + root_addr * 32 + 0x1D] = 0;
} else {
gDisk_buff[0x400 + root_addr * 32 + 0x1C] = m % 256;
gDisk_buff[0x400 + root_addr * 32 + 0x1D] = m / 256;
}
gRewriteflag[(p_file - ROOT_SECTOR + 0x200) / 0x400] = 1;
memcpy(p_file, str, strlen((char *) str));
ReWriteFlsash();
}
} else {
if ((p_file = SearchFile("LOGOIN BMP", &file_len, &root_addr))) {
memcpy(str, p_file, 254);
memset(gDisk_buff, 0x00, 0x2600);
memcpy(ROOT_SECTOR + 32, "LOGOIN BMP", 0xC);
memcpy(FILE_SECTOR + 512, str, 254);
gDisk_buff[0x40B + 32] = 0x0; //<2F><><EFBFBD><EFBFBD>
*(u32*) (VOLUME_BASE + 32) = VOLUME;
gDisk_buff[0x41A + 32] = 0x03; //<2F>غ<EFBFBD>
gDisk_buff[0x41C + 32] = 254; //<2F>ļ<EFBFBD><C4BC><EFBFBD>С
} else {
memset(gDisk_buff, 0x00, 0x2600);
}
memcpy(ROOT_SECTOR, "CONFIG TXT", 0xC);
memcpy(FAT1_SECTOR, gFat_data, 6);
memcpy(FAT2_SECTOR, gFat_data, 6);
m = 0;
for (k = 0; k < CONFIG_CONT; k++) {
memcpy(FILE_SECTOR + m, gDef_set[k], strlen((char *) gDef_set[k]));
m += strlen((char *) gDef_set[k]);
memcpy(FILE_SECTOR + m, gSet_range[k],
strlen((char *) gSet_range[k]));
m += strlen((char *) gSet_range[k]);
}
gDisk_buff[0x40B] = 0x0;
*(u32*) VOLUME_BASE = VOLUME;
gDisk_buff[0x41A] = 0x02;
gDisk_buff[0x41C] = m;
ReWrite_All();
}
gVar[F_TYPE] = HEX;
gVar[F_FLAG] = RDY;
gVar[SEG_ST] = 0;
gV32[OFFSET] = 0;
gV32[COUNT] = 0;
gV32[WR_CNT] = 0;
gV32[RD_CNT] = 0;
return 0;
}
/*******************************************************************************
Function: Disk_SecWrite
Description:
Inputs:
*******************************************************************************/
void Disk_SecWrite(u8* pbuffer, u32 diskaddr) {
u32 i, j, k, m, flag;
u8 t_p[CONFIG_CONT][ROW_CONT];
u8 str[FILE_CONT];
u8 ver[20];
static u16 Config_flag = 0;
if (diskaddr == 0x1000) { // Write FAT1 sector
if (memcmp(pbuffer, (u8*) FAT1_SECTOR, 512)) { //check different
memcpy((u8*) FAT1_SECTOR, pbuffer, 512);
gRewriteflag[0] = 1;
}
} else if (diskaddr == 0x2800) { // Write FAT2 sector
if (memcmp(pbuffer, (u8*) FAT2_SECTOR, 512)) { //check different
memcpy((u8*) FAT2_SECTOR, pbuffer, 512);
gRewriteflag[0] = 1;
}
} else if (diskaddr == 0x4000) { // Write DIR sector
if (memcmp(pbuffer, (u8*) ROOT_SECTOR, 512)) { //check different
memcpy((u8*) ROOT_SECTOR, pbuffer, 512);
gRewriteflag[1] = 1;
for (i = 0; i < 16; i++) {
memcpy((u8*) ver, (u8*) (pbuffer), 12); //copy the filename out for comparison
if (memcmp(ver, "CONFIG TXT", 11) == 0) { //if file name matches
Config_flag = pbuffer[0x1A];
break;
}
pbuffer += 32; //move to the next chunk of the pbuffer
}
}
} else if (diskaddr >= 0x8000 && diskaddr <= 0xA000) { // Write FILE sector
if (memcmp(pbuffer, (u8*) (FILE_SECTOR + (diskaddr - 0x8000)), 512)) { //check if different
memcpy((u8*) (FILE_SECTOR + (diskaddr - 0x8000)), pbuffer, 512);
}
if ((((diskaddr - 0x8000) / 0x200) + 2) == Config_flag) {
m = 0;
memset(t_p, 0x00, CONFIG_CONT * ROW_CONT);
memcpy((u8*) (gFile_con), pbuffer, 512);
for (k = 0; k < CONFIG_CONT; k++) { //
j = 0;
for (i = m; i < strlen((char *) gFile_con); i++) { //
if (gFile_con[i] == 0x0D && gFile_con[i + 1] == 0x0A)
break;
else {
if (j < ROW_CONT)
t_p[k][j++] = gFile_con[i];
m++;
}
}
t_p[k][j] = '\0';
m = i + 2;
}
for (k = 0; k < CONFIG_CONT; k++) {
if (memcmp(t_p[k], gKey_words[k], strlen(gKey_words[k])) == 0) {
flag = 0;
for (i = strlen(gKey_words[k]); i < strlen((char *) t_p[k]);
i++) {
if (t_p[k][i] >= '0' && t_p[k][i] <= '9') {
if (t_p[k][i] == '0') {
if (k == 6) {
flag = 1;
break;
} else {
flag = 0;
break;
}
}
flag = 1;
break;
} else if ((t_p[k][i] != 0x20) && (t_p[k][i] != 0x3d)) {
flag = 0;
break;
}
}
if ((!flag) || (!Cal_Val(t_p[k] + i, k, 1))) {
return;
} else {
Set_Ver(t_p[k] + i, k);
memset(t_p[k], 0, strlen((char *) t_p[k]));
if (k == 0)
sprintf((char *) t_p[k], "T_Standby=%d",
device_info.t_standby / 10);
else if (k == 1)
sprintf((char *) t_p[k], "T_Work=%d",
device_info.t_work / 10);
else if (k == 2)
sprintf((char *) t_p[k], "Wait_Time=%ld",
device_info.wait_time / 100);
else if (k == 3)
sprintf((char *) t_p[k], "Idle_Time=%ld",
device_info.idle_time / 100);
else if (k == 4)
sprintf((char *) t_p[k], "T_Step=%d",
device_info.t_step / 10);
else if (k == 5)
sprintf((char *) t_p[k], "Turn_Off_v=%ld",
gTurn_offv / 10);
else if (k == 6)
sprintf((char *) t_p[k], "TempShowFlag=%d",
Get_TemperatureShowFlag());
else if (k == 7)
sprintf((char *) t_p[k], "ZeroP_Ad=%ld", gZerop_ad);
}
} else {
memcpy(t_p[k], gDef_set[k], strlen((char *) gDef_set[k]));
return;
}
}
memset(str, 0, FILE_CONT);
for (k = 0; k < CONFIG_CONT; k++) {
strcat((char *) str, (char *) t_p[k]);
strcat((char *) str, (char *) gSet_range[k]);
}
m = strlen((char *) str);
gDisk_buff[0x400 + (Config_flag - 2) * 32 + 0x1C] = m % 256;
gDisk_buff[0x400 + (Config_flag - 2) * 32 + 0x1D] = m / 256;
memcpy((u8*) (FILE_SECTOR), (u8*) str, 512);
gRewriteflag[1] = 1;
gRewriteflag[((diskaddr - 0x8000 + 0x200) / 0x400) + 1] = 1;
ReWriteFlsash();
return;
}
gRewriteflag[1] = 1;
gRewriteflag[((diskaddr - 0x8000 + 0x200) / 0x400) + 1] = 1;
ReWriteFlsash();
}
ReWriteFlsash();
}
/*******************************************************************************
Function: Disk_SecRead
Description: Reads a sector from the virtual disk
*******************************************************************************/
void Disk_SecRead(u8* pbuffer, u32 disk_addr) {
Soft_Delay();
if (disk_addr == 0x0000) { // Read BOOT sector
memcpy(pbuffer, BOOT_SEC, 512);
} else if (disk_addr == 0x1000) { // Read FAT1 sector
memcpy(pbuffer, FAT1_SECTOR, 512);
} else if (disk_addr == 0x2800) { // Read FAT2 sector
memcpy(pbuffer, FAT2_SECTOR, 512);
} else if (disk_addr == 0x4000) { // Read DIR sector
memcpy(pbuffer, (u8*) (ROOT_SECTOR), 512);
} else if (disk_addr >= 0x8000 && disk_addr <= 0xA000) { // Read FILE sector
memcpy(pbuffer, (u8*) (APP_BASE + 0x600 + (disk_addr - 0x8000)), 512);
} else {
memset(pbuffer, 0, 512); //unknown, return 0's
}
}
/*******************************************************************************
Function:ReWriteFlsash
Description:
Output:RDY(all good) or ERR (error)
*******************************************************************************/
u8 ReWriteFlsash(void) {
u32 i, j;
u8 result;
u16 *f_buff;
FLASH_Unlock();
for (i = 0; i < 16; i++) {
if (gRewriteflag[i]) {
gRewriteflag[i] = 0;
FLASH_Erase(APP_BASE + i * 0x400);
f_buff = (u16*) &gDisk_buff[i * 0x400];
for (j = 0; j < 0x400; j += 2) { //Loop through the 1k block
result = FLASH_Prog((u32) (APP_BASE + i * 0x400 + j), //program each 16 bit block
*f_buff++);
if (result != FLASH_COMPLETE) { //something went wrong
FLASH_Lock(); //make sure the flash is locked again
return ERR; //return ERR
}
}
break;
}
}
FLASH_Lock();
return RDY;
}
/*******************************************************************************
Function: ReWrite_All
Description:
Output:
*******************************************************************************/
u8 ReWrite_All(void) {
u16 i;
u8 result;
u16 *f_buff = (u16*) gDisk_buff;
FLASH_Unlock();
for (i = 0; i < 9; i++)
FLASH_Erase(APP_BASE + i * 0x400);
for (i = 0; i < 0X2600; i += 2) {
result = FLASH_Prog((u32) (APP_BASE + i), *f_buff++);
if (result != FLASH_COMPLETE)
return ERR;
}
FLASH_Lock();
return RDY;
}
/*******************************************************************************
Function:Erase
Description: Erase the first 9k from APP_BASE
*******************************************************************************/
void Erase(void) {
u16 i;
FLASH_Unlock(); //unlock the mcu flash controller
for (i = 0; i < 9; i++)
FLASH_Erase(APP_BASE + i * 0x400); //erase the flash
FLASH_Lock();
}
/*******************************************************************************
Function: Read_Memory
Description:
*******************************************************************************/
void Read_Memory(u32 r_offset, u32 r_length) {
static u32 offset, length, block_offset;
if (gVar[USB_ST] == TXFR_IDLE) {
offset = r_offset * SECTOR_SIZE;
length = r_length * SECTOR_SIZE;
gVar[USB_ST] = TXFR_ONGOING;
}
if (gVar[USB_ST] == TXFR_ONGOING) {
if (!gV32[RD_CNT]) {
Disk_SecRead(gBuff, offset);
UserToPMABufferCopy(gBuff, ENDP1_TXADDR, BULK_MAX_PACKET_SIZE);
gV32[RD_CNT] = SECTOR_SIZE - BULK_MAX_PACKET_SIZE;
block_offset = BULK_MAX_PACKET_SIZE;
} else {
UserToPMABufferCopy(gBuff + block_offset, ENDP1_TXADDR,
BULK_MAX_PACKET_SIZE);
gV32[RD_CNT] -= BULK_MAX_PACKET_SIZE;
block_offset += BULK_MAX_PACKET_SIZE;
}
SetEPTxCount(ENDP1, BULK_MAX_PACKET_SIZE);
SetEPTxStatus(ENDP1, EP_TX_VALID);
offset += BULK_MAX_PACKET_SIZE;
length -= BULK_MAX_PACKET_SIZE;
CSW.dDataResidue -= BULK_MAX_PACKET_SIZE;
}
if (length == 0) {
gV32[RD_CNT] = 0;
block_offset = 0;
offset = 0;
Bot_State = BOT_DATA_IN_LAST;
gVar[USB_ST] = TXFR_IDLE;
}
}
/*******************************************************************************
Function: Write_Memory
Description:
*******************************************************************************/
void Write_Memory(u32 w_offset, u32 w_length) {
static u32 offset, length;
u32 idx, temp = gV32[WR_CNT] + 64;
if (gVar[USB_ST] == TXFR_IDLE) {
offset = w_offset * SECTOR_SIZE;
length = w_length * SECTOR_SIZE;
gVar[USB_ST] = TXFR_ONGOING;
}
if (gVar[USB_ST] == TXFR_ONGOING) {
for (idx = 0; gV32[WR_CNT] < temp; gV32[WR_CNT]++)
*(u8 *) (gBuff + gV32[WR_CNT]) = Bulk_Buff[idx++];
offset += Data_Len;
length -= Data_Len;
if (!(length % SECTOR_SIZE)) {
gV32[WR_CNT] = 0;
Disk_SecWrite(gBuff, offset - SECTOR_SIZE);
}
CSW.dDataResidue -= Data_Len;
SetEPRxStatus(ENDP2, EP_RX_VALID); /* enable the next transaction*/
}
if ((length == 0) || (Bot_State == BOT_CSW_Send)) {
gV32[WR_CNT] = 0;
Set_CSW(CSW_CMD_PASSED, SEND_CSW_ENABLE);
gVar[USB_ST] = TXFR_IDLE;
}
}
/********************************* END OF FILE ******************************/

View File

@@ -1,198 +0,0 @@
/********************* (C) COPYRIGHT 2015 e-Design Co.,Ltd. ********************
File Name : EXT_Flash.c
Version : S100 APP Ver 2.11
Description:
Author : bure
Data:
History:
*******************************************************************************/
#include <string.h>
#include <stdio.h>
#include "Ext_Flash.h"
#include "Bios.h"
#define OK 0 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#define SEC_ERR 1 // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д<EFBFBD><D0B4><EFBFBD><EFBFBD>
#define TMAX 100000 // <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
u32 Mass_Memory_Size;
u32 Mass_Block_Size;
u32 Mass_Block_Count;
u32 Tout;
u8 flash_mode;
void ExtFLASH_SectorErase(u32 SectorAddr);
/*******************************************************************************
SPI_FLASH_SectorErase : Sector Erases the specified FLASH Page.(4k/sector)
*******************************************************************************/
void ExtFLASH_SectorErase(u32 SectorAddr)
{
ExtFlash_WriteEnable();
ExtFlash_CS_LOW();
ExtFlash_SendByte(SE);
ExtFlash_SendByte((SectorAddr & 0xFF0000) >> 16); //Send high address byte
ExtFlash_SendByte((SectorAddr & 0xFF00) >> 8); //Send medium address byte
ExtFlash_SendByte(SectorAddr & 0xFF); //Send low address byte
ExtFlash_CS_HIGH();
ExtFlash_WaitForWriteEnd(); // Wait the end of Flash writing
}
void ExtFlash_PageWR(u8* pBuffer, u32 WriteAddr)
{
u32 addr,i,j;
u8* ptr;
u8 page=0,flag=0,write_mode;
u8 buffer[256];
flag=0;
if(flash_mode==FLASH_8M) {
addr=WriteAddr & 0xFFF000;
page=16;
} else {
page=1;
addr=WriteAddr & 0xFFFF00;
}
while(page>0) {
ExtFlash_PageRD((u8*)&buffer,addr, 256);
for(j=0; j<255; j++) {
if(buffer[j++]!=0xff) {
flag=1;
break;
}
}
addr+=256;
page--;
}
if(flash_mode==FLASH_8M) {
page=16;
addr=WriteAddr & 0xFFF000;
if(flag==1)ExtFLASH_SectorErase(addr);
write_mode=PP;
} else {
page=1;
addr=WriteAddr & 0xFFFF00;
if(flag==1)write_mode=PW;
else write_mode=PP;
}
ptr=pBuffer;
for(i=0; i<page; i++) {
ExtFlash_PageProg(ptr, addr,write_mode);
addr+=256;
ptr+=256;
}
}
/*******************************************************************************
дFLASHҳ(256 Bytes)<29><> Mode=0: <20><>0<EFBFBD><30>1<EFBFBD><31><EFBFBD>ݸ<EFBFBD>д Mode=1: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>д
*******************************************************************************/
void ExtFlash_PageProg(u8* pBuffer, u32 WriteAddr,u8 CMD)
{
u16 Lenght = 256;
ExtFlash_CS_HIGH();
ExtFlash_WaitForWriteEnd();
ExtFlash_WriteEnable();
ExtFlash_CS_LOW();
ExtFlash_SendByte(CMD);
ExtFlash_SendByte((WriteAddr & 0xFF0000) >> 16);
ExtFlash_SendByte((WriteAddr & 0xFF00) >> 8);
ExtFlash_SendByte(WriteAddr & 0xFF);
while(Lenght--) { // while there is data to be written on the FLASH
ExtFlash_SendByte((*pBuffer));
pBuffer++;
}
ExtFlash_CS_HIGH();
ExtFlash_WaitForWriteEnd();
}
/*******************************************************************************
SPI_FLASH_BufferRead
*******************************************************************************/
void ExtFlash_PageRD(u8* pBuffer, u32 ReadAddr, u16 Lenght)
{
ExtFlash_CS_HIGH();
ExtFlash_WaitForWriteEnd();
ExtFlash_CS_LOW();
ExtFlash_SendByte(READ);
ExtFlash_SendByte((ReadAddr & 0xFF0000) >> 16);
ExtFlash_SendByte((ReadAddr& 0xFF00) >> 8);
ExtFlash_SendByte(ReadAddr & 0xFF);
while(Lenght--) { // while there is data to be read
*pBuffer = (ExtFlash_SendByte(Dummy_Byte));
pBuffer++;
}
ExtFlash_CS_HIGH();
}
/*******************************************************************************
SPI_FLASH_ReadByte
*******************************************************************************/
u8 ExtFlash_ReadByte(void)
{
return (ExtFlash_SendByte(Dummy_Byte));
}
/*******************************************************************************
SPI_FLASH_SendByte
*******************************************************************************/
u8 ExtFlash_SendByte(u8 byte)
{
Tout = 0;
while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET) {
if(Tout++ > TMAX) return 255;
}
SPI_I2S_SendData(SPI3, byte);
Tout = 0;
while(SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_RXNE) == RESET) {
if(Tout++ > TMAX) return 255;
}
return SPI_I2S_ReceiveData(SPI3);
}
/*******************************************************************************
SPI_FLASH_WriteEnable
*******************************************************************************/
void ExtFlash_WriteEnable(void)
{
ExtFlash_CS_LOW();
ExtFlash_SendByte(WREN);
ExtFlash_CS_HIGH();
}
/*******************************************************************************
SPI_FLASH_WaitForWriteEnd
*******************************************************************************/
void ExtFlash_WaitForWriteEnd(void)
{
u8 FLASH_Status = 0;
ExtFlash_CS_LOW();
ExtFlash_SendByte(RDSR);
Tout = 0;
do {
FLASH_Status = ExtFlash_SendByte(Dummy_Byte);
if(Tout++ > TMAX) return;
} while((FLASH_Status & WIP_Flag) == SET); // Write in progress
ExtFlash_CS_HIGH();
}
/*******************************************************************************
MAL_GetStatus
*******************************************************************************/
void MAL_GetStatus (void)
{
if(flash_mode==FLASH_8M) {
Mass_Block_Count = 2048; //FLASH_SIZE/FLASH_PAGE_SIZE;
Mass_Block_Size = 512*8; //FLASH_PAGE_SIZE; 4096
Mass_Memory_Size = 512*4096*4 ; //FLASH_SIZE; 0x800000;
} else {
Mass_Block_Count = 4096; //FLASH_SIZE/FLASH_PAGE_SIZE; 4096
Mass_Block_Size = 512; //FLASH_PAGE_SIZE;
Mass_Memory_Size = 512*4096 ; //FLASH_SIZE; 0x200000;
}
}
/********************************* END OF FILE ******************************/

View File

@@ -2,7 +2,7 @@
/* Brief : Interrupt Service Routines Author : bure */
/******************************************************************************/
#include "Interrupt.h"
#include "usb_istr.h"
#include "Bios.h"
#include "I2C.h"
@@ -54,7 +54,7 @@ void SysTick_Handler(void) {
/******************************************************************************/
void USB_LP_CAN1_RX0_IRQHandler(void) {
USB_Istr();
}
void TIM2_IRQHandler(void) {
TIM2_ISR();

View File

@@ -11,9 +11,8 @@
#include <string.h>
#include <stdio.h>
#include "APP_Version.h"
#include "Disk.h"
#include "Bios.h"
#include "usb_lib.h"
#include "I2C.h"
#include "Flash.h"
#include "MMA8652FC.h"
@@ -23,32 +22,27 @@
#include "Hardware.h"
int main(void) {
RCC_Config(); //setup system clock
NVIC_Config(0x4000);
//NVIC_Config(0x4000);
NVIC_Config(0x0000);
Init_Timer2(); //init the timers
Init_Timer3();
GPIO_Config();//setup all the GPIO pins
USB_Port(DISABLE);//disable the USB hardware
Delay_Ms(200);//pause to let hardware stabilize
USB_Port(ENABLE);//enable the USB hardware
USB_Init();
GPIO_Config(); //setup all the GPIO pins
Init_Timer3();
I2C_Configuration(); //init the i2c bus
Adc_Init(); //init adc and dma
if (Get_CtrlStatus() != CONFIG)
StartUp_Accelerated();//start the accelerometer if not in config mode
StartUp_Accelerated(); //start the accelerometer if not in config mode
System_Init();//load known safe values
Init_Oled();//init the OLED display
Clear_Screen();//clear the display buffer to black
Init_Gtime();//init the count down timers
APP_Init();//pick operating mode via input voltage
System_Init(); //load known safe values
Init_Oled(); //init the OLED display
Clear_Screen(); //clear the display buffer to black
Init_Gtime(); //init the count down timers
APP_Init(); //pick operating mode via input voltage
Disk_BuffInit();//fill the buffer for the virtual disk
Config_Analysis(); //read in config from virtual disk
Pid_Init(); //init the pid to starting values
Set_gKey(NO_KEY); //reset keys to all off
Start_Watchdog(3000);//start the system watchdog as 3 seconds
Start_Watchdog(3000); //start the system watchdog as 3 seconds
while (1) {
Clear_Watchdog(); //reset the Watchdog

View File

@@ -15,7 +15,7 @@
#include "Bios.h"
#include "I2C.h"
#include "Hardware.h"
#include "Disk.h"
#include "UI.h"

View File

@@ -17,7 +17,7 @@
#include "Bios.h"
#include "Oled.h"
#include "Hardware.h"
#include "Disk.h"
#include "MMA8652FC.h"
/******************************************************************************/
u8 gTemp_array[16 * 16 + 16];
@@ -143,20 +143,20 @@ void Display_Temp(u8 x, s16 temp) {
}
/*******************************************************************************
Function:
Description:
Description: Shows the press the button to start screen
*******************************************************************************/
void Show_Notice(void) {
int j, k;
static u8* ptr0;
static u8 posi = 0, i = 0;
if (i == 0) { //1
//This draws the soldering iron logo to prompt the user to press the button to wake
if (i == 0) { //1 Button up
ptr0 = Oled_DrawArea(0, 0, 96, 16, (u8*) Maplib);
} else if (i == 1) { //2
} else if (i == 1) { //2 Button down
ptr0 = Oled_DrawArea(0, 0, 96, 16, ptr0);
} else if (i == 2) { //3
} else if (i == 2) { //3 Button up
ptr0 = Oled_DrawArea(0, 0, 96, 16, (u8*) Maplib);
} else if (i == 3) { //4
} else if (i == 3) { //4 Draw sliding text in
for (j = 0; j < 6; j++) {
k = 84;
while (k >= posi) {

View File

@@ -1,269 +0,0 @@
/******************** (C) COPYRIGHT 2015 e-Design Co., Ltd. ********************
File Name : USB_bot.c
Version : STM32_USB Disk Ver 3.4 Author : MCD Application Team & bure
*******************************************************************************/
#include "usb_scsi.h"
#include "usb_regs.h"
#include "usb_mem.h"
#include "usb_conf.h"
#include "usb_bot.h"
#include "usb_prop.h"
u8 Bot_State;
u8 Bulk_Buff[BULK_MAX_PACKET_SIZE]; // Data_ data buffer
u16 Data_Len;
Bulk_Only_CBW CBW;
Bulk_Only_CSW CSW;
u32 SCSI_LBA , SCSI_BlkLen;
/*******************************************************************************
Mass_Storage_In: Mass Storage IN transfer.
*******************************************************************************/
void Mass_Storage_In (void)
{
switch (Bot_State)
{
case BOT_CSW_Send:
case BOT_ERROR:
Bot_State = BOT_IDLE;
SetEPRxStatus(ENDP2, EP_RX_VALID);/* enable the Endpoint to receive the next cmd*/
break;
case BOT_DATA_IN:
switch (CBW.CB[0])
{
case SCSI_READ10:
SCSI_Read10_Cmd(SCSI_LBA , SCSI_BlkLen);
break;
}
break;
case BOT_DATA_IN_LAST:
Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
SetEPRxStatus(ENDP2, EP_RX_VALID);
break;
default:
break;
}
}
/*******************************************************************************
Mass_Storage_Out: Mass Storage OUT transfer.
*******************************************************************************/
void Mass_Storage_Out (void)
{
u8 CMD;
CMD = CBW.CB[0];
Data_Len = GetEPRxCount(ENDP2);
PMAToUserBufferCopy(Bulk_Buff, ENDP2_RXADDR, Data_Len);
switch (Bot_State)
{
case BOT_IDLE:
CBW_Decode();
break;
case BOT_DATA_OUT:
if (CMD == SCSI_WRITE10)
{
SCSI_Write10_Cmd(SCSI_LBA , SCSI_BlkLen);
break;
}
Bot_Abort(DIR_OUT);
Set_Scsi_Sense_Data(ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
Set_CSW (CSW_PHASE_ERROR, SEND_CSW_DISABLE);
break;
default:
Bot_Abort(BOTH_DIR);
Set_Scsi_Sense_Data(ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
Set_CSW (CSW_PHASE_ERROR, SEND_CSW_DISABLE);
break;
}
}
/*******************************************************************************
CBW_Decode: Decode the received CBW and call the related SCSI command
*******************************************************************************/
void CBW_Decode(void)
{
u32 Counter;
for (Counter = 0; Counter < Data_Len; Counter++)
{
*((u8 *)&CBW + Counter) = Bulk_Buff[Counter];
}
CSW.dTag = CBW.dTag;
CSW.dDataResidue = CBW.dDataLength;
if (Data_Len != BOT_CBW_PACKET_LENGTH)
{
Bot_Abort(BOTH_DIR);
// reset the CBW.dSignature to desible the clear feature until receiving a Mass storage reset
CBW.dSignature = 0;
Set_Scsi_Sense_Data(ILLEGAL_REQUEST, PARAMETER_LIST_LENGTH_ERROR);
Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
return;
}
if ((CBW.CB[0] == SCSI_READ10 ) || (CBW.CB[0] == SCSI_WRITE10 ))
{
// Calculate Logical Block Address
SCSI_LBA = (CBW.CB[2] << 24) | (CBW.CB[3] << 16) | (CBW.CB[4] << 8) | CBW.CB[5];
// Calculate the Number of Blocks to transfer
SCSI_BlkLen = (CBW.CB[7] << 8) | CBW.CB[8];
}
if (CBW.dSignature == BOT_CBW_SIGNATURE)
{
// Valid CBW
if ((CBW.bLUN > Max_Lun) || (CBW.bCBLength < 1) || (CBW.bCBLength > 16))
{
Bot_Abort(BOTH_DIR);
Set_Scsi_Sense_Data(ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
}
else
{
switch (CBW.CB[0])
{
case SCSI_REQUEST_SENSE:
SCSI_RequestSense_Cmd ();
break;
case SCSI_INQUIRY:
SCSI_Inquiry_Cmd();
break;
case SCSI_START_STOP_UNIT:
SCSI_Start_Stop_Unit_Cmd();
break;
case SCSI_ALLOW_MEDIUM_REMOVAL:
SCSI_Start_Stop_Unit_Cmd();
break;
case SCSI_MODE_SENSE6:
SCSI_ModeSense6_Cmd ();
break;
case SCSI_MODE_SENSE10:
SCSI_ModeSense10_Cmd ();
break;
case SCSI_READ_FORMAT_CAPACITIES:
SCSI_ReadFormatCapacity_Cmd();
break;
case SCSI_READ_CAPACITY10:
SCSI_ReadCapacity10_Cmd();
break;
case SCSI_TEST_UNIT_READY:
SCSI_TestUnitReady_Cmd();
break;
case SCSI_READ10:
SCSI_Read10_Cmd(SCSI_LBA , SCSI_BlkLen);
break;
case SCSI_WRITE10:
SCSI_Write10_Cmd(SCSI_LBA , SCSI_BlkLen);
break;
case SCSI_VERIFY10:
SCSI_Verify10_Cmd();
break;
//Unsupported command
case SCSI_MODE_SELECT10:
SCSI_Mode_Select10_Cmd();
break;
case SCSI_MODE_SELECT6:
SCSI_Mode_Select6_Cmd();
break;
case SCSI_SEND_DIAGNOSTIC:
SCSI_Send_Diagnostic_Cmd();
break;
case SCSI_READ6:
SCSI_Read6_Cmd();
break;
case SCSI_READ12:
SCSI_Read12_Cmd();
break;
case SCSI_READ16:
SCSI_Read16_Cmd();
break;
case SCSI_READ_CAPACITY16:
SCSI_READ_CAPACITY16_Cmd();
break;
case SCSI_WRITE6:
SCSI_Write6_Cmd();
break;
case SCSI_WRITE12:
SCSI_Write12_Cmd();
break;
case SCSI_WRITE16:
SCSI_Write16_Cmd();
break;
case SCSI_VERIFY12:
SCSI_Verify12_Cmd();
break;
case SCSI_VERIFY16:
SCSI_Verify16_Cmd();
break;
default:
{
Bot_Abort(BOTH_DIR);
Set_Scsi_Sense_Data(ILLEGAL_REQUEST, INVALID_COMMAND);
Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
}
}
}
}
else
{
// Invalid CBW
Bot_Abort(BOTH_DIR);
Set_Scsi_Sense_Data(ILLEGAL_REQUEST, INVALID_COMMAND);
Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
}
}
/*******************************************************************************
Transfer_Data_Request: Send the request response to the PC HOST.
Input : u8* Data_Address : point to the data to transfer.
u16 Data_Length : the nember of Bytes to transfer.
*******************************************************************************/
void Transfer_Data_Request(u8* Data_Pointer, u16 Data_Len)
{
UserToPMABufferCopy(Data_Pointer, ENDP1_TXADDR, Data_Len);
SetEPTxCount(ENDP1, Data_Len);
SetEPTxStatus(ENDP1, EP_TX_VALID);
Bot_State = BOT_DATA_IN_LAST;
CSW.dDataResidue -= Data_Len;
CSW.bStatus = CSW_CMD_PASSED;
}
/*******************************************************************************
Set_CSW: Set the SCW with the needed fields.
Input : u8 CSW_Status this filed can be CSW_CMD_PASSED,CSW_CMD_FAILED,
or CSW_PHASE_ERROR.
*******************************************************************************/
void Set_CSW (u8 CSW_Status, u8 Send_Permission)
{
CSW.dSignature = BOT_CSW_SIGNATURE;
CSW.bStatus = CSW_Status;
UserToPMABufferCopy(((u8 *)& CSW), ENDP1_TXADDR, CSW_DATA_LENGTH);
SetEPTxCount(ENDP1, CSW_DATA_LENGTH);
Bot_State = BOT_ERROR;
if (Send_Permission){
Bot_State = BOT_CSW_Send;
SetEPTxStatus(ENDP1, EP_TX_VALID);
}
}
/*******************************************************************************
Bot_Abort: Stall the needed Endpoint according to the selected direction.
Input : Endpoint direction IN, OUT or both directions
*******************************************************************************/
void Bot_Abort(u8 Direction)
{
switch (Direction){
case DIR_IN :
SetEPTxStatus(ENDP1, EP_TX_STALL);
break;
case DIR_OUT :
SetEPRxStatus(ENDP2, EP_RX_STALL);
break;
case BOTH_DIR :
SetEPTxStatus(ENDP1, EP_TX_STALL);
SetEPRxStatus(ENDP2, EP_RX_STALL);
break;
default:
break;
}
}
/********************************* END OF FILE ******************************/

View File

@@ -1,109 +0,0 @@
/******************** (C) COPYRIGHT 2015 e-Design Co., Ltd. ********************
File Name : USB_desc.c
Version : STM32_USB Disk Ver 3.4 Author : MCD Application Team & bure
*******************************************************************************/
#include "usb_desc.h"
const u8 MASS_DeviceDescriptor[MASS_SIZ_DEVICE_DESC] ={
0x12, /* bLength */
0x01, /* bDescriptorType */
0x00, /* bcdUSB, version 2.00 */
0x02,
0x00, /* bDeviceClass : each interface define the device class */
0x00, /* bDeviceSubClass */
0x00, /* bDeviceProtocol */
0x40, /* bMaxPacketSize0 0x40 = 64 */
0x83, /* idVendor (0483) */
0x04,
0x20, /* idProduct */
0x57,
0x00, /* bcdDevice 2.00*/
0x02,
1, /* index of string Manufacturer */
/**/
2, /* index of string descriptor of product*/
/* */
3, /* */
/* */
/* */
0x01 /*bNumConfigurations */
};
const u8 MASS_ConfigDescriptor[MASS_SIZ_CONFIG_DESC] ={
0x09, /* bLength: Configuation Descriptor size */
0x02, /* bDescriptorType: Configuration */
MASS_SIZ_CONFIG_DESC,
0x00,
0x01, /* bNumInterfaces: 1 interface */
0x01, /* bConfigurationValue: */
/* Configuration value */
0x00, /* iConfiguration: */
/* Index of string descriptor */
/* describing the configuration */
0xC0, /* bmAttributes: */
/* bus powered */
0x32, /* MaxPower 100 mA */
/******************** Descriptor of Mass Storage interface ********************/
/* 09 */
0x09, /* bLength: Interface Descriptor size */
0x04, /* bDescriptorType: */
/* Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x02, /* bNumEndpoints*/
0x08, /* bInterfaceClass: MASS STORAGE Class */
0x06, /* bInterfaceSubClass : SCSI transparent*/
0x50, /* nInterfaceProtocol */
4, /* iInterface: */
/* 18 */
0x07, /*Endpoint descriptor length = 7*/
0x05, /*Endpoint descriptor type */
0x81, /*Endpoint address (IN, address 1) */
0x02, /*Bulk endpoint type */
0x40, /*Maximum packet size (64 bytes) */
0x00,
0x00, /*Polling interval in milliseconds */
/* 25 */
0x07, /*Endpoint descriptor length = 7 */
0x05, /*Endpoint descriptor type */
0x02, /*Endpoint address (OUT, address 2) */
0x02, /*Bulk endpoint type */
0x40, /*Maximum packet size (64 bytes) */
0x00,
0x00 /*Polling interval in milliseconds*/
/*32*/
};
const u8 MASS_StringLangID[MASS_SIZ_STRING_LANGID] ={
MASS_SIZ_STRING_LANGID,
0x03,
0x09,
0x04
}; // LangID = 0x0409: U.S. English //
const u8 MASS_StringVendor[MASS_SIZ_STRING_VENDOR] ={
MASS_SIZ_STRING_VENDOR, // Size of manufaturer string //
0x03, // bDescriptorType = String descriptor //
// Manufacturer: "STMicroelectronics" //
'S', 0, 'T', 0, 'M', 0, 'i', 0, 'c', 0, 'r', 0, 'o', 0, 'e', 0,
'l', 0, 'e', 0, 'c', 0, 't', 0, 'r', 0, 'o', 0, 'n', 0, 'i', 0,
'c', 0, 's', 0
};
const u8 MASS_StringProduct[MASS_SIZ_STRING_PRODUCT] ={
MASS_SIZ_STRING_PRODUCT,
0x03,
// Product name: "STM32F10x:USB Mass Storage" //
'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, ' ', 0, 'M', 0, 'a', 0, 's', 0,
's', 0, ' ', 0, 'S', 0, 't', 0, 'o', 0, 'r', 0, 'a', 0, 'g', 0, 'e', 0
};
u8 MASS_StringSerial[MASS_SIZ_STRING_SERIAL] ={
MASS_SIZ_STRING_SERIAL,
0x03,
// Serial number//
'S', 0, 'T', 0, 'M', 0, '3', 0, '2', 0, '1', 0, '0', 0
};
const u8 MASS_StringInterface[MASS_SIZ_STRING_INTERFACE] ={
MASS_SIZ_STRING_INTERFACE,
0x03,
// Interface 0: "ST Mass" //
'S', 0, 'T', 0, ' ', 0, 'M', 0, 'a', 0, 's', 0, 's', 0
};
/********************************* END OF FILE ******************************/

View File

@@ -1,138 +0,0 @@
/******************** (C) COPYRIGHT 2015 e-Design Co., Ltd. ********************
File Name : USB_istr.c
Version : STM32 USB Disk Ver 3.4 Author : MCD Application Team & bure
*******************************************************************************/
#include "usb_type.h"
#include "usb_regs.h"
#include "usb_pwr.h"
#include "usb_istr.h"
#include "usb_init.h"
#include "usb_int.h"
#include "usb_bot.h"
volatile u16 wIstr; /* ISTR register last read value */
volatile u8 bIntPackSOF = 0; /* SOFs received between 2 consecutive packets */
void (*pEpInt_IN[7])(void) ={
EP1_IN_Callback,
EP2_IN_Callback,
EP3_IN_Callback,
EP4_IN_Callback,
EP5_IN_Callback,
EP6_IN_Callback,
EP7_IN_Callback,
};
void (*pEpInt_OUT[7])(void) ={
EP1_OUT_Callback,
EP2_OUT_Callback,
EP3_OUT_Callback,
EP4_OUT_Callback,
EP5_OUT_Callback,
EP6_OUT_Callback,
EP7_OUT_Callback,
};
/*******************************************************************************
USB_Istr: ISTR events interrupt service routine
*******************************************************************************/
void USB_Istr(void)
{
wIstr = _GetISTR();
#if (IMR_MSK & ISTR_RESET)
if (wIstr & ISTR_RESET & wInterrupt_Mask){
// _SetISTR((u16)CLR_RESET);
Device_Property.Reset();
_SetISTR((u16)CLR_RESET);
//#ifdef RESET_CALLBACK
// RESET_Callback();
//#endif
}
#endif
//-----------------------------------------------------------------------------
#if (IMR_MSK & ISTR_DOVR)
if (wIstr & ISTR_DOVR & wInterrupt_Mask){
_SetISTR((u16)CLR_DOVR);
//#ifdef DOVR_CALLBACK
// DOVR_Callback();
//#endif
}
#endif
//-----------------------------------------------------------------------------
#if (IMR_MSK & ISTR_ERR)
if (wIstr & ISTR_ERR & wInterrupt_Mask){
_SetISTR((u16)CLR_ERR);
//#ifdef ERR_CALLBACK
// ERR_Callback();
//#endif
}
#endif
//-----------------------------------------------------------------------------
#if (IMR_MSK & ISTR_WKUP)
if (wIstr & ISTR_WKUP & wInterrupt_Mask){
// _SetISTR((u16)CLR_WKUP);
Resume(RESUME_EXTERNAL);
_SetISTR((u16)CLR_WKUP);
//#ifdef WKUP_CALLBACK
// WKUP_Callback();
//#endif
}
#endif
//-----------------------------------------------------------------------------
#if (IMR_MSK & ISTR_SUSP)
if (wIstr & ISTR_SUSP & wInterrupt_Mask){ // check if SUSPEND is possible
if (fSuspendEnabled) Suspend();
else Resume(RESUME_LATER); // if not possible then resume after xx ms
_SetISTR((u16)CLR_SUSP); // clear of the ISTR bit must be done after setting of CNTR_FSUSP
//#ifdef SUSP_CALLBACK
// SUSP_Callback();
//#endif
}
#endif
//-----------------------------------------------------------------------------
#if (IMR_MSK & ISTR_SOF)
if (wIstr & ISTR_SOF & wInterrupt_Mask){
_SetISTR((u16)CLR_SOF);
bIntPackSOF++;
//#ifdef SOF_CALLBACK
// SOF_Callback();
//#endif
}
#endif
//-----------------------------------------------------------------------------
#if (IMR_MSK & ISTR_ESOF)
if (wIstr & ISTR_ESOF & wInterrupt_Mask){
// _SetISTR((u16)CLR_ESOF); // resume handling timing is made with ESOFs
Resume(RESUME_ESOF); // request without change of the machine state
_SetISTR((u16)CLR_ESOF); // resume handling timing is made with ESOFs
//#ifdef ESOF_CALLBACK
// ESOF_Callback();
//#endif
}
#endif
//-----------------------------------------------------------------------------
#if (IMR_MSK & ISTR_CTR)
if (wIstr & ISTR_CTR & wInterrupt_Mask){
/* servicing of the endpoint correct transfer interrupt */
/* clear of the CTR flag into the sub */
CTR_LP();
//#ifdef CTR_CALLBACK
// CTR_Callback();
//#endif
}
#endif
} /* USB_Istr */
/*******************************************************************************
EP1_IN_Callback: EP1 IN Callback Routine
*******************************************************************************/
void EP1_IN_Callback(void)
{
Mass_Storage_In();
}
/*******************************************************************************
EP2_OUT_Callback: EP2 OUT Callback Routine.
*******************************************************************************/
void EP2_OUT_Callback(void)
{
Mass_Storage_Out();
}
/********************************* END OF FILE ******************************/

View File

@@ -1,262 +0,0 @@
/******************** (C) COPYRIGHT 2015 e-Design Co., Ltd. ********************
File Name : USB_prop.c
Version : STM32 USB Disk Ver 3.4 Author : MCD Application Team & bure
*******************************************************************************/
#include "usb_desc.h"
#include "usb_pwr.h"
#include "usb_bot.h"
#include "usb_prop.h"
#include "usb_lib.h"
#include "Bios.h"
#include "APP_Version.h"
u32 Max_Lun = 0;
DEVICE Device_Table ={ EP_NUM, 1 };
DEVICE_PROP Device_Property ={
MASS_init,
MASS_Reset,
MASS_Status_In,
MASS_Status_Out,
MASS_Data_Setup,
MASS_NoData_Setup,
MASS_Get_Interface_Setting,
MASS_GetDeviceDescriptor,
MASS_GetConfigDescriptor,
MASS_GetStringDescriptor,
0,
0x40 // MAX PACKET SIZE
};
USER_STANDARD_REQUESTS User_Standard_Requests ={
Mass_Storage_GetConfiguration,
Mass_Storage_SetConfiguration,
Mass_Storage_GetInterface,
Mass_Storage_SetInterface,
Mass_Storage_GetStatus,
Mass_Storage_ClearFeature,
Mass_Storage_SetEndPointFeature,
Mass_Storage_SetDeviceFeature,
Mass_Storage_SetDeviceAddress
};
ONE_DESCRIPTOR Device_Descriptor ={
(u8*)MASS_DeviceDescriptor,
MASS_SIZ_DEVICE_DESC
};
ONE_DESCRIPTOR Config_Descriptor ={
(u8*)MASS_ConfigDescriptor,
MASS_SIZ_CONFIG_DESC
};
ONE_DESCRIPTOR String_Descriptor[5] ={
{(u8*)MASS_StringLangID, MASS_SIZ_STRING_LANGID},
{(u8*)MASS_StringVendor, MASS_SIZ_STRING_VENDOR},
{(u8*)MASS_StringProduct, MASS_SIZ_STRING_PRODUCT},
{(u8*)MASS_StringSerial, MASS_SIZ_STRING_SERIAL},
{(u8*)MASS_StringInterface, MASS_SIZ_STRING_INTERFACE},
};
/*******************************************************************************
MASS_init: Mass Storage init routine.
*******************************************************************************/
void MASS_init()
{
Get_SerialNum(); // Update the serial number string descriptor with the data from the unique ID
pInformation->Current_Configuration = 0;
PowerOn(); // Connect the device
_SetISTR(0); // USB interrupts initialization. clear pending interrupts
wInterrupt_Mask = IMR_MSK;
_SetCNTR(wInterrupt_Mask); // set interrupts mask
bDeviceState = UNCONNECTED;
}
/*******************************************************************************
MASS_Reset: Mass Storage reset routine.
*******************************************************************************/
void MASS_Reset()
{
Device_Info.Current_Configuration = 0; // Set the device as not configured
pInformation->Current_Feature = MASS_ConfigDescriptor[7]; // Current Feature initialization
SetBTABLE(BTABLE_ADDRESS);
// Initialize Endpoint 0
SetEPType(ENDP0, EP_CONTROL);
SetEPTxStatus(ENDP0, EP_TX_NAK);
SetEPRxAddr(ENDP0, ENDP0_RXADDR);
SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
SetEPTxAddr(ENDP0, ENDP0_TXADDR);
Clear_Status_Out(ENDP0);
SetEPRxValid(ENDP0);
//Initialize Endpoint 1
SetEPType(ENDP1, EP_BULK);
SetEPTxAddr(ENDP1, ENDP1_TXADDR);
SetEPTxStatus(ENDP1, EP_TX_NAK);
SetEPRxStatus(ENDP1, EP_RX_DIS);
// Initialize Endpoint 2
SetEPType(ENDP2, EP_BULK);
SetEPRxAddr(ENDP2, ENDP2_RXADDR);
SetEPRxCount(ENDP2, Device_Property.MaxPacketSize);
SetEPRxStatus(ENDP2, EP_RX_VALID);
SetEPTxStatus(ENDP2, EP_TX_DIS);
SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);
SetEPRxValid(ENDP0);
// Set the device to response on default address
SetDeviceAddress(0);
bDeviceState = ATTACHED;
CBW.dSignature = BOT_CBW_SIGNATURE;
Bot_State = BOT_IDLE;
}
/*******************************************************************************
Mass_Storage_SetConfiguration: Handle the SetConfiguration request.
*******************************************************************************/
void Mass_Storage_SetConfiguration(void)
{
if (pInformation->Current_Configuration != 0){
bDeviceState = CONFIGURED; // Device configured
ClearDTOG_TX(ENDP1);
ClearDTOG_RX(ENDP2);
Bot_State = BOT_IDLE; // set the Bot state machine to the IDLE state
}
}
/*******************************************************************************
Mass_Storage_ClearFeature: Handle the ClearFeature request.
*******************************************************************************/
void Mass_Storage_ClearFeature(void)
{
/* when the host send a CBW with invalid signature or invalid length the two
Endpoints (IN & OUT) shall stall until receiving a Mass Storage Reset */
if (CBW.dSignature != BOT_CBW_SIGNATURE)
Bot_Abort(BOTH_DIR);
}
/*******************************************************************************
Mass_Storage_SetConfiguration: Udpade the device state to addressed.
*******************************************************************************/
void Mass_Storage_SetDeviceAddress (void)
{
bDeviceState = ADDRESSED;
}
/*******************************************************************************
MASS_Status_In: Mass Storage Status IN routine.
*******************************************************************************/
void MASS_Status_In(void)
{
return;
}
/*******************************************************************************
MASS_Status_Out: Mass Storage Status OUT routine.
*******************************************************************************/
void MASS_Status_Out(void)
{
return;
}
/*******************************************************************************
MASS_Data_Setup: Handle the data class specific requests.
*******************************************************************************/
RESULT MASS_Data_Setup(u8 RequestNo)
{
u8* (*CopyRoutine)(u16);
CopyRoutine = NULL;
if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
&& (RequestNo == GET_MAX_LUN) && (pInformation->USBwValue == 0)
&& (pInformation->USBwIndex == 0) && (pInformation->USBwLength == 0x01))
{
CopyRoutine = Get_Max_Lun;
} else return USB_UNSUPPORT;
if (CopyRoutine == NULL) return USB_UNSUPPORT;
pInformation->Ctrl_Info.CopyData = CopyRoutine;
pInformation->Ctrl_Info.Usb_wOffset = 0;
(*CopyRoutine)(0);
return USB_SUCCESS;
}
/*******************************************************************************
MASS_NoData_Setup: Handle the no data class specific requests.
*******************************************************************************/
RESULT MASS_NoData_Setup(u8 RequestNo)
{
if ((Type_Recipient == (CLASS_REQUEST | INTERFACE_RECIPIENT))
&& (RequestNo == MASS_STORAGE_RESET) && (pInformation->USBwValue == 0)
&& (pInformation->USBwIndex == 0) && (pInformation->USBwLength == 0x00))
{
ClearDTOG_TX(ENDP1); // Initialize Endpoint 1
ClearDTOG_RX(ENDP2); // Initialize Endpoint 2
CBW.dSignature = BOT_CBW_SIGNATURE; // intialise the CBW signature to enable the clear feature
Bot_State = BOT_IDLE;
return USB_SUCCESS;
}
return USB_UNSUPPORT;
}
/*******************************************************************************
MASS_Get_Interface_Setting: Test the interface and the alternate setting
according to the supported one.
*******************************************************************************/
RESULT MASS_Get_Interface_Setting(u8 Interface, u8 AlternateSetting)
{
if (AlternateSetting > 0) return USB_UNSUPPORT;// in this application we don't have AlternateSetting
else if (Interface > 0) return USB_UNSUPPORT; // in this application we have only 1 interfaces
return USB_SUCCESS;
}
/*******************************************************************************
MASS_GetDeviceDescriptor: Get the device descriptor.
*******************************************************************************/
u8 *MASS_GetDeviceDescriptor(u16 Length)
{
return Standard_GetDescriptorData(Length, &Device_Descriptor );
}
/*******************************************************************************
MASS_GetConfigDescriptor: Get the configuration descriptor.
*******************************************************************************/
u8 *MASS_GetConfigDescriptor(u16 Length)
{
return Standard_GetDescriptorData(Length, &Config_Descriptor );
}
/*******************************************************************************
MASS_GetStringDescriptor: Get the string descriptors according to
the needed index.
*******************************************************************************/
u8 *MASS_GetStringDescriptor(u16 Length)
{
u8 wValue0 = pInformation->USBwValue0;
if (wValue0 > 5) return NULL;
else return Standard_GetDescriptorData(Length, &String_Descriptor[wValue0]);
}
/*******************************************************************************
Get_Max_Lun: Handle the Get Max Lun request.
*******************************************************************************/
u8 *Get_Max_Lun(u16 Length)
{
if (Length == 0){
pInformation->Ctrl_Info.Usb_wLength = LUN_DATA_LENGTH;
return 0;
} else return((u8*)(&Max_Lun));
}
/*******************************************************************************
Get_SerialNum : Create the serial number string descriptor.
*******************************************************************************/
void Get_SerialNum(void)
{
u32 Device_Serial0, Device_Serial1, Device_Serial2;
Device_Serial0 = SERIAL_NO1;
Device_Serial1 = SERIAL_NO2;
Device_Serial2 = SERIAL_NO3;
if (Device_Serial0 != 0){
MASS_StringSerial[ 2] = (u8)( Device_Serial0 & 0x000000FF);
MASS_StringSerial[ 4] = (u8)((Device_Serial0 & 0x0000FF00) >> 8);
MASS_StringSerial[ 6] = (u8)((Device_Serial0 & 0x00FF0000) >> 16);
MASS_StringSerial[ 8] = (u8)((Device_Serial0 & 0xFF000000) >> 24);
MASS_StringSerial[10] = (u8)( Device_Serial1 & 0x000000FF);
MASS_StringSerial[12] = (u8)((Device_Serial1 & 0x0000FF00) >> 8);
MASS_StringSerial[14] = (u8)((Device_Serial1 & 0x00FF0000) >> 16);
MASS_StringSerial[16] = (u8)((Device_Serial1 & 0xFF000000) >> 24);
MASS_StringSerial[18] = (u8)( Device_Serial2 & 0x000000FF);
MASS_StringSerial[20] = (u8)((Device_Serial2 & 0x0000FF00) >> 8);
MASS_StringSerial[22] = (u8)((Device_Serial2 & 0x00FF0000) >> 16);
MASS_StringSerial[24] = (u8)((Device_Serial2 & 0xFF000000) >> 24);
}
}
/********************************* END OF FILE ******************************/

View File

@@ -1,152 +0,0 @@
/******************** (C) COPYRIGHT 2015 e-Design Co., Ltd. ********************
File Name : USB_pwr.c
Version : STM32 USB Disk Ver 3.4 Author : MCD Application Team & bure
*******************************************************************************/
#include "usb_lib.h"
#include "usb_conf.h"
#include "usb_pwr.h"
vu32 bDeviceState = UNCONNECTED; // USB device status
vu8 fSuspendEnabled = TRUE; // true when suspend is possible
struct{
volatile RESUME_STATE eState;
volatile u8 bESOFcnt;
} ResumeS;
/*******************************************************************************
PowerOn Return : USB_SUCCESS
*******************************************************************************/
RESULT PowerOn(void)
{
u16 wRegVal;
/*** CNTR_PWDN = 0 ***/
wRegVal = CNTR_FRES;
_SetCNTR(wRegVal);
/*** CNTR_FRES = 0 ***/
wInterrupt_Mask = 0;
_SetCNTR(wInterrupt_Mask);
/*** Clear pending interrupts ***/
_SetISTR(0);
/*** Set interrupt mask ***/
wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;
_SetCNTR(wInterrupt_Mask);
return USB_SUCCESS;
}
/*******************************************************************************
PowerOff: handles switch-off conditions Return : USB_SUCCESS
*******************************************************************************/
RESULT PowerOff()
{
/* disable all ints and force USB reset */
_SetCNTR(CNTR_FRES);
/* clear interrupt status register */
_SetISTR(0);
/* Disable the Pull-Up*/
// USB_Cable_Config(DISABLE);
/* switch-off device */
_SetCNTR(CNTR_FRES + CNTR_PDWN);
/* sw variables reset */
/* ... */
return USB_SUCCESS;
}
/*******************************************************************************
Suspend: sets suspend mode operating conditions
Return : USB_SUCCESS.
*******************************************************************************/
void Suspend(void)
{
u16 wCNTR;
/* suspend preparation */
/* macrocell enters suspend mode */
wCNTR = _GetCNTR();
wCNTR |= CNTR_FSUSP;
_SetCNTR(wCNTR);
/* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */
/* power reduction */
/* ... on connected devices */
/* force low-power mode in the macrocell */
wCNTR = _GetCNTR();
wCNTR |= CNTR_LPMODE;
_SetCNTR(wCNTR);
}
/*******************************************************************************
Resume_Init: Handles wake-up restoring normal operations
* Return : USB_SUCCESS.
*******************************************************************************/
void Resume_Init(void)
{
u16 wCNTR;
/* ------------------ ONLY WITH BUS-POWERED DEVICES ---------------------- */
/* restart the clocks */
/* CNTR_LPMODE = 0 */
wCNTR = _GetCNTR();
wCNTR &= (~CNTR_LPMODE);
_SetCNTR(wCNTR);
/* restore full power */
/* ... on connected devices */
/* reset FSUSP bit */
_SetCNTR(IMR_MSK);
/* reverse suspend preparation */
/* ... */
}
/*******************************************************************************
Resume: This is the state machine handling resume operations and
timing sequence. The control is based on the Resume structure
variables and on the ESOF interrupt calling this subroutine
without changing machine state.
Input: a state machine value (RESUME_STATE)
RESUME_ESOF doesn't change ResumeS.eState allowing
decrementing of the ESOF counter in different states.
*******************************************************************************/
void Resume(RESUME_STATE eResumeSetVal)
{
u16 wCNTR;
if (eResumeSetVal != RESUME_ESOF) ResumeS.eState = eResumeSetVal;
switch (ResumeS.eState){
case RESUME_EXTERNAL:
Resume_Init();
ResumeS.eState = RESUME_OFF;
break;
case RESUME_INTERNAL:
Resume_Init();
ResumeS.eState = RESUME_START;
break;
case RESUME_LATER:
ResumeS.bESOFcnt = 2;
ResumeS.eState = RESUME_WAIT;
break;
case RESUME_WAIT:
ResumeS.bESOFcnt--;
if (ResumeS.bESOFcnt == 0)
ResumeS.eState = RESUME_START;
break;
case RESUME_START:
wCNTR = _GetCNTR();
wCNTR |= CNTR_RESUME;
_SetCNTR(wCNTR);
ResumeS.eState = RESUME_ON;
ResumeS.bESOFcnt = 10;
break;
case RESUME_ON:
ResumeS.bESOFcnt--;
if (ResumeS.bESOFcnt == 0){
wCNTR = _GetCNTR();
wCNTR &= (~CNTR_RESUME);
_SetCNTR(wCNTR);
ResumeS.eState = RESUME_OFF;
}
break;
case RESUME_OFF:
case RESUME_ESOF:
default:
ResumeS.eState = RESUME_OFF;
break;
}
}
/********************************* END OF FILE ******************************/

View File

@@ -1,230 +0,0 @@
/******************** (C) COPYRIGHT 2015 e-Design Co., Ltd. ********************
File Name : USB_scsi.c
Version : STM32 USB Disk Ver 3.4 Author : MCD Application Team & bure
*******************************************************************************/
#include "usb_scsi.h"
#include "usb_bot.h"
#include "usb_regs.h"
#include "usb_lib.h"
#include "Disk.h"
u8 Page00_Inquiry_Data[] ={ 0, 0, 0, 0, 0};
u8 Mode_Sense6_data[] ={0x03, 0x00, 0x00, 0x00};
u8 Mode_Sense10_data[] ={0x00, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
u8 Scsi_Sense_Data[] ={0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
u8 ReadCapacity10_Data[] ={ 0, 0, 0, 0, 0, 0, 0, 0};
u8 ReadFormatCapacity[] ={ 0, 0, 0, 8, 0, 0, 0, 0, 2, 0, 0, 0};
#ifdef DFU_MODE
uc8 Disk_Inquiry_Str[] ={0x00, 0x80, 0x02, 0x02, 36-4, 0x00, 0x00, 0x00,
'V', 'i', 'r', 't', 'u', 'a', 'l', ' ',
'D', 'F', 'U', ' ', 'D', 'i', 's', 'k',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', };
#else
uc8 Disk_Inquiry_Str[] ={0x00, 0x80, 0x02, 0x02, 36-4, 0x00, 0x00, 0x00,
'M', 'i', 'n', 'i', ' ', 'D', 'S', 'O',
'D', 'i', 's', 'k', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
' ', ' ', ' ', ' ', };
#endif
/*******************************************************************************
SCSI_Inquiry_Cmd: SCSI Inquiry Command routine.
*******************************************************************************/
void SCSI_Inquiry_Cmd(void)
{
u8* Inquiry_Data;
u16 Inquiry_Data_Length;
if (CBW.CB[1] & 0x01){ // Evpd is set
Inquiry_Data = Page00_Inquiry_Data;
Inquiry_Data_Length = 5;
} else {
Inquiry_Data = (u8*)Disk_Inquiry_Str;
if (CBW.CB[4] <= STANDARD_INQUIRY_DATA_LEN) Inquiry_Data_Length = CBW.CB[4];
else Inquiry_Data_Length = STANDARD_INQUIRY_DATA_LEN;
}
Transfer_Data_Request(Inquiry_Data, Inquiry_Data_Length);
}
/*******************************************************************************
SCSI_ReadFormatCapacity_Cmd: SCSI ReadFormatCapacity Command routine.
*******************************************************************************/
void SCSI_ReadFormatCapacity_Cmd(void)
{
ReadFormatCapacity[ 4] = (u8)(SECTOR_SIZE >> 24);
ReadFormatCapacity[ 5] = (u8)(SECTOR_SIZE >> 16);
ReadFormatCapacity[ 6] = (u8)(SECTOR_SIZE >> 8);
ReadFormatCapacity[ 7] = (u8)(SECTOR_SIZE);
ReadFormatCapacity[ 9] = (u8)(SECTOR_SIZE >> 16);
ReadFormatCapacity[10] = (u8)(SECTOR_SIZE >> 8);
ReadFormatCapacity[11] = (u8)(SECTOR_SIZE);
Transfer_Data_Request(ReadFormatCapacity, READ_FORMAT_CAPACITY_DATA_LEN);
}
/*******************************************************************************
SCSI_ReadCapacity10_Cmd: SCSI ReadCapacity10 Command routine.
*******************************************************************************/
void SCSI_ReadCapacity10_Cmd(void)
{
ReadCapacity10_Data[0] = (u8)(SECTOR_CNT - 1 >> 24);
ReadCapacity10_Data[1] = (u8)(SECTOR_CNT - 1 >> 16);
ReadCapacity10_Data[2] = (u8)(SECTOR_CNT - 1 >> 8);
ReadCapacity10_Data[3] = (u8)(SECTOR_CNT - 1);
ReadCapacity10_Data[4] = (u8)(SECTOR_SIZE >> 24);
ReadCapacity10_Data[5] = (u8)(SECTOR_SIZE >> 16);
ReadCapacity10_Data[6] = (u8)(SECTOR_SIZE >> 8);
ReadCapacity10_Data[7] = (u8)(SECTOR_SIZE);
Transfer_Data_Request(ReadCapacity10_Data, READ_CAPACITY10_DATA_LEN);
}
/*******************************************************************************
SCSI_ModeSense6_Cmd: SCSI ModeSense6 Command routine.
*******************************************************************************/
void SCSI_ModeSense6_Cmd (void)
{
Transfer_Data_Request(Mode_Sense6_data, MODE_SENSE6_DATA_LEN);
}
/*******************************************************************************
SCSI_ModeSense10_Cmd: SCSI ModeSense10 Command routine.
*******************************************************************************/
void SCSI_ModeSense10_Cmd (void)
{
Transfer_Data_Request(Mode_Sense10_data, MODE_SENSE10_DATA_LEN);
}
/*******************************************************************************
SCSI_RequestSense_Cmd: SCSI RequestSense Command routine.
*******************************************************************************/
void SCSI_RequestSense_Cmd (void)
{
u8 Request_Sense_data_Length;
if (CBW.CB[4] <= REQUEST_SENSE_DATA_LEN) Request_Sense_data_Length = CBW.CB[4];
else Request_Sense_data_Length = REQUEST_SENSE_DATA_LEN;
Transfer_Data_Request(Scsi_Sense_Data, Request_Sense_data_Length);
}
/*******************************************************************************
Set_Scsi_Sense_Data: Set Scsi Sense Data routine.
*******************************************************************************/
void Set_Scsi_Sense_Data(u8 Sens_Key, u8 Asc)
{
Scsi_Sense_Data[2] = Sens_Key;
Scsi_Sense_Data[12] = Asc;
}
/*******************************************************************************
SCSI_Start_Stop_Unit_Cmd: SCSI Start_Stop_Unit Command routine.
*******************************************************************************/
void SCSI_Start_Stop_Unit_Cmd(void)
{
Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
}
/*******************************************************************************
SCSI_Read10_Cmd: SCSI Read10 Command routine.
*******************************************************************************/
void SCSI_Read10_Cmd(u32 LBA , u32 BlockNbr)
{
if (Bot_State == BOT_IDLE){
if (!(SCSI_Address_Management(SCSI_READ10, LBA, BlockNbr))) return;//address out of range
if ((CBW.bmFlags & 0x80) != 0){
Bot_State = BOT_DATA_IN;
Read_Memory(LBA , BlockNbr);
} else {
Bot_Abort(BOTH_DIR);
Set_Scsi_Sense_Data(ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
Set_CSW (CSW_CMD_FAILED, SEND_CSW_ENABLE);
}
return;
} else if (Bot_State == BOT_DATA_IN) Read_Memory(LBA , BlockNbr);
}
/*******************************************************************************
SCSI_Write10_Cmd: SCSI Write10 Command routine.
*******************************************************************************/
void SCSI_Write10_Cmd(u32 LBA , u32 BlockNbr)
{
if (Bot_State == BOT_IDLE){
if (!(SCSI_Address_Management(SCSI_WRITE10 , LBA, BlockNbr))) return;//address out of range
if ((CBW.bmFlags & 0x80) == 0){
Bot_State = BOT_DATA_OUT;
SetEPRxStatus(ENDP2, EP_RX_VALID);
} else {
Bot_Abort(DIR_IN);
Set_Scsi_Sense_Data(ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
}
return;
} else if (Bot_State == BOT_DATA_OUT) Write_Memory(LBA , BlockNbr);
}
/*******************************************************************************
SCSI_Verify10_Cmd: SCSI Verify10 Command routine.
*******************************************************************************/
void SCSI_Verify10_Cmd(void)
{
if ((CBW.dDataLength == 0) && !(CBW.CB[1] & BLKVFY)){ // BLKVFY not set
Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
} else {
Bot_Abort(BOTH_DIR);
Set_Scsi_Sense_Data(ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
}
}
/*******************************************************************************
SCSI_Valid_Cmd: Valid Commands routine.
*******************************************************************************/
void SCSI_Valid_Cmd(void)
{
if (CBW.dDataLength != 0){
Bot_Abort(BOTH_DIR);
Set_Scsi_Sense_Data(ILLEGAL_REQUEST, INVALID_COMMAND);
Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
} else Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
}
/*******************************************************************************
SCSI_Valid_Cmd: Valid Commands routine.
*******************************************************************************/
void SCSI_TestUnitReady_Cmd(void)
{
Set_CSW (CSW_CMD_PASSED, SEND_CSW_ENABLE);
}
/*******************************************************************************
SCSI_Invalid_Cmd: Invalid Commands routine
*******************************************************************************/
void SCSI_Invalid_Cmd(void)
{
if (CBW.dDataLength == 0) Bot_Abort(DIR_IN);
else{
if ((CBW.bmFlags & 0x80) != 0) Bot_Abort(DIR_IN);
else Bot_Abort(BOTH_DIR);
}
Set_Scsi_Sense_Data(ILLEGAL_REQUEST, INVALID_COMMAND);
Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
}
/*******************************************************************************
SCSI_Address_Management: Test the received address.
Input: Cmd the command can be SCSI_READ10 or SCSI_WRITE10.
Return: Read\Write status (bool).
*******************************************************************************/
u8 SCSI_Address_Management(u8 Cmd , u32 LBA , u32 BlockNbr)
{
if ((LBA + BlockNbr) > SECTOR_CNT){
if (Cmd == SCSI_WRITE10) Bot_Abort(BOTH_DIR);
Bot_Abort(DIR_IN);
Set_Scsi_Sense_Data(ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);
Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
return (FALSE);
}
if (CBW.dDataLength != BlockNbr * SECTOR_SIZE){
if (Cmd == SCSI_WRITE10) Bot_Abort(BOTH_DIR);
else Bot_Abort(DIR_IN);
Set_Scsi_Sense_Data(ILLEGAL_REQUEST, INVALID_FIELED_IN_COMMAND);
Set_CSW (CSW_CMD_FAILED, SEND_CSW_DISABLE);
return (FALSE);
}
return (TRUE);
}
/********************************* END OF FILE ******************************/