Перейти к содержанию
    

lecko

Участник
  • Постов

    10
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный

Информация о lecko

  • День рождения 02.09.1988

Контакты

  • Сайт
    Array
  • ICQ
    Array
  1. LPC2478 IAP

    И еще раз всем привет! Собственно, возник следующий вопрос. Прошивка по USB успешно выполняется. То есть почти успешно... Уточню детали реализации. Вся память с помощью scatter-файла разбита на 2 региона: 0x0-0x60000 и 0x60000-0x80000. В первом содержится, собственно, обновляемый код, а во втором - код, вызывающий IAP-функции и отключающий прерывания на время их работы. Основной код (в первом регионе) получает данные по USB и записывает их в RAM, а затем, опять же по команде с USB, управление передается на код, расположенный во второй области памяти, осуществляющий перепрошивку. После перепрошивки предполагается аппаратная перезагрузка. Утилита для перепрошивки по СОМ (FlashMagic) сравнивает содержимое памяти с исходным хекс файлом и говорит что все ок. Однако контроллер до следующей перепрошивки по кому не работает. Вопрос: почему? Не надо ли помимо собственно перепрошивки дополнительно изменять какие-то служебные области? Или в чем еще может быть дело?
  2. LPC2478 IAP

    Всем привет! Имеется устройство на основе LPC2478, которое, в том числе, умеет подключаться как Mass Storage Device и обрабатывать произвольные SCSI-команды с компьютера. Возникла необходимость сделать обновление прошивки через USB. Я узнал, что контроллер поддерживает IAP-функции, позволяющие модифицировать содержимое встроенной памяти. Таким образом, предполагается создать код, который будет либо подгружать прошивку, либо передавать на нее управление. Среда разработки - Keil uVision 4. Вопросы: 1) как корректно интрепретировать HEХ-файл, создаваемый кейлом? где про это можно прочитать? 2) Как правильно разместить прошивку в памяти? 3) У кого нибудь есть примеры кода с подобным функционалом? 4) Можно ли (если да, то как) скомпилировать кейлом код, который корректно разместится НЕ по нулевому адресу? Полдня гуглил, ничего не нашел :( Заранее спасибо!
  3. Всем привет! Имеется устройство на базе МК LPC2478, которое при подключении к компьютеру определяется как Mass Storage Device. Имеется код, который по специальной команде (отличающейся от стандартной команды чтения) должен послать 512 байт из массива. Вот код BYTE * buffer=(BYTE * )malloc(sizeof(BYTE)*512); DWORD res; BYTE i=0,j=0; CSW.dDataResidue = 512; BulkStage=MSC_BS_DATA_IN; fill(0,buffer,135,1);//заполняем массив while(CSW.dDataResidue>0) { delayMs(0,1); USB_WriteEP(MSC_EP_IN, (BYTE*)&mci_buffer[i*64],64); CSW.dDataResidue-=64; i++; } BulkStage = MSC_BS_DATA_IN_LAST; CSW.bStatus = CSW_CMD_PASSED; free(mci_buffer); В таком виде код работает. Однако если удалить строчку delayMs(0,1); , то передача не проходит. Насколько я понимаю, для отработки функции USB_WriteEP требуется какое-то время. Код функции USB_WriteEP взят из стандартной библиотеки Keil DWORD USB_WriteEP (DWORD EPNum, BYTE *pData, DWORD cnt) { DWORD n; USB_CTRL = ((EPNum & 0x0F) << 2) | CTRL_WR_EN; TX_PLENGTH = cnt; for (n = 0; n < (cnt + 3) / 4; n++) { TX_DATA = *((__packed DWORD *)pData); pData += 4; } USB_CTRL = 0; WrCmd(CMD_SEL_EP(EPAdr(EPNum))); WrCmd(CMD_VALID_BUF); return (cnt); } Вопрос: можно ли как-то отследить состояние выполнения записи на endpoint (например, через какой-нибудь регистр) и в этом ли вообще дело? Или, выражаясь по-другому, как избавиться от функции задержки?
  4. В продолжение темы. При отладке SPI столкнулся с очень странным глюком. Я пытаюсь послать команду на запись в буфер DataFlash последовательности байт по нулевому адресу. Код выглядит так: BYTE init_buffer[]={0x84,0x00,0x00,0x00};//опкод и адрес FIO4CLR=1<<21;//инверсный Chip Select SSP1Send(init_buffer,4);//собственно, послали ... FIO4SET=1<<21;инверсный Chip Select Вот так выглядит функция SSP1Send: void SSP1Send( BYTE *buf, DWORD Length ) { DWORD i; for ( i = 0; i < Length; i++ ) { /* as long as TNF bit is set (TxFIFO is not full), I can always transmit */ while ( !(SSP1SR & SSPSR_TNF) ); SSP1DR = *buf; buf++; /* Wait until the Busy bit is cleared */ while ( !(SSP1SR & SSPSR_BSY) ); } return; } На логическом анализаторе видно, что после отправки 1 байта (0х84) Chip Select самопроизвольно переходит обратно в единицу, таким образом все последующие байты игнорируются. Если вызвать функцию SSP1Send с такими параметрами 2 раза, то же происходит после отправки 3 байт. Что это такое? может ли микросхема DataFlash сама поднимать Chip Select?
  5. Просто и логично) спасибо, помогло! Для тех, кто будет в том же танке что и я прилагаю код, который необходимо добавить: BYTE i,Dummy; for(i=0;i<FIFOSIZE;i++) Dummy=SSP1DR;
  6. Имеется тестовый код для ARM7, запрашивающий ID у микросхемы Atmel SPI DataFlash: void SSP1Send( BYTE *buf, DWORD Length ) { DWORD i; for ( i = 0; i < Length; i++ ) { /* as long as TNF bit is set (TxFIFO is not full), I can always transmit */ while ( !(SSP1SR & SSPSR_TNF) ); SSP1DR = *buf; buf++; /* Wait until the Busy bit is cleared */ while ( !(SSP1SR & SSPSR_BSY) ); } return; } void SSP1Receive( BYTE *buf, DWORD Length ) { DWORD i; for ( i = 0; i < Length; i++ ) { /* As long as Receive FIFO is not empty, I can always receive. */ /* since it's a loopback test, clock is shared for both TX and RX, no need to write dummy byte to get clock to get the data */ /* if it's a peer-to-peer communication, SSPDR needs to be written before a read can take place. */ SSP1DR = 0xFF; while ( !(SSP1SR & SSPSR_RNE) ); *buf = SSP1DR; buf++; } return; } ... for (n = 0; n < 3; n++) { UART_printf(0,"Try readback ID from DataFlash: "); data_send[0]=0x9f; SSP1Send(data_send,1); FIO4CLR = 1<<21; SSP1Receive(data_recv,7); FIO4SET = 1<<21; TFT_printf(0,"Read: 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x 0x%x \n\r",data_recv[0],data_recv[1],data_recv[2],data_recv[3],data_recv[4],data_recv[5],data_recv[6]); } В соответствии с даташитом ответ должен быть такой: 0x1f 0x27 0x1 0x0 На практике имеем следующее: Try readback ID from DataFlash: Read: 0xff 0x1f 0x27 0x1 0x0 0x0 0x0 Try readback ID from DataFlash: Read: 0xff 0xff 0x1f 0x27 0x1 0x0 0x0 Try readback ID from DataFlash: Read: 0xff 0xff 0x1f 0x27 0x1 0x0 0x0 Логический анализатор показал, что все нормально, на нем этих 0xff нет (точнее есть один, в момент получения команды). Откуда берутся эти "мусорные" байты?
  7. Сделал. Вторая версия кода: #define IENABLE __asm { MRS sysreg, SPSR; MSR CPSR_c, #SYS32Mode } #define IDISABLE __asm { MSR CPSR_c, #(IRQ32Mode|I_Bit); MSR SPSR_cxsf, sysreg } ... DWORD install_irq( DWORD IntNumber, void *HandlerAddr, DWORD Priority ) { DWORD *vect_addr; DWORD *vect_cntl; VICIntEnClr = 1 << IntNumber; if ( IntNumber >= VIC_SIZE ) { return ( FALSE ); } else { vect_addr = (DWORD *)(VIC_BASE_ADDR + VECT_ADDR_INDEX + IntNumber*4); vect_cntl = (DWORD *)(VIC_BASE_ADDR + VECT_CNTL_INDEX + IntNumber*4); *vect_addr = (DWORD)HandlerAddr; *vect_cntl = Priority; VICIntEnable = 1 << IntNumber; return( TRUE ); } } ... void UARTHandler (void) __irq { IENABLE; install_irq(MCI_INT, (void*)MCI_IRQHandler, HIGHEST_PRIORITY);//включаем прерывание ... //тут происходит вызов функции, инициирующей срабатывание вложенного прерывания ... VICIntEnClr = 1 << IntNumber;//отключаем прерывание IDISABLE; VICVectAddr = 0; } Все равно не работает :(
  8. Спасибо за ответ! В соответствии с общими указаниями сделано следующее: Так выглядит код внешнего прерывания: #define IENABLE __asm { MRS sysreg, SPSR; MSR CPSR_c, #SYS32Mode } #define IDISABLE __asm { MSR CPSR_c, #(IRQ32Mode|I_Bit); MSR SPSR_cxsf, sysreg } ... void UARTHandler (void) __irq { IENABLE; ... //тут происходит вызов функции, инициирующей срабатывание вложенного прерывания ... IDISABLE; VICVectAddr = 0; } В коде внутреннего прерывания никаких специальных действий не происходит. Оба прерывания зарегистрированы с высшим приоритетом. Документация по компилятору RealView, который я использую, утверждает, что адреса возврата сохранять не надо - компилятор-де делает это автоматически. Вопрос - почему во внутреннее прерывание не передается управление?
  9. Всем привет! У кого-нибудь есть работающий пример вложенных прерываний под LPC-2478? Облазил и форумы, и документацию - везде только общие рекомендации:(
  10. sk-mlpc2478 не работает UART

    Всем привет! Начал программировать для платы SK-MLPC2478. попробовал скомпилировать код из книги Тревора (привожу ниже). Однако, никакого вывода в терминале не вижу вообще. Догадываюсь, что что-то криво настроено, однако пока разобраться не могу. в чем может быть причина? #include <lpc23xx.h> #include "LCD.h" void init_serial (void); unsigned char putchar (unsigned char ch); unsigned char getchar (void); unsigned int flasher = 0x0000000; int main (void) { unsigned int delay; // /* Reset all GPIO pins to default: primary function */ PINSEL0 = 0x00000000; PINSEL1 = 0x00000000; PINSEL2 = 0x00000000; PINSEL3 = 0x00000000; PINSEL4 = 0x00000000; PINSEL5 = 0x00000000; PINSEL6 = 0x00000000; PINSEL7 = 0x00000000; PINSEL8 = 0x00000000; PINSEL9 = 0x00000000; PINSEL10 = 0x00000000; IODIR0 = 0x00000000; IODIR1 = 0x00000000; IOSET0 = 0x00000000; IOSET1 = 0x00000000; FIO0DIR = 0x00000000; FIO1DIR = 0x00000000; FIO2DIR = 0x00000000; FIO3DIR = 0x00000000; FIO4DIR = 0x00000000; FIO0SET = 0x00000000; FIO1SET = 0x00000000; FIO2SET = 0x00000000; FIO3SET = 0x00000000; FIO4SET = 0x00000000; FIO2DIR = 0x000000FF; FIO2MASK = 0xFFFFFF00; init_serial(); putchar('o'); while(1) { putchar(getchar()); } return 0; } void init_serial (void) /* Initialize Serial Interface */ { PINSEL0 |= 0x40000000; /* Enable TxD1 */ PINSEL1 |= 0x00000001; /* Enable RxD1 */ PCLKSEL0 = 0x02 << 8; //set UART clock to 30Mkz U1LCR = 0x00000083; /* 8 bits, no Parity, 1 Stop bit */ U1DLL = 0x000000C3; /* 9600 Baud Rate @ 30MHz VPB Clock */ U1DLM = 0x00000000; U1LCR = 0x00000003; /* DLAB = 0 */ } unsigned char putchar (unsigned char ch) /* Write character to Serial Port */ { while (!(U1LSR & 0x20)); return (U1THR = ch); } unsigned char getchar (void) /* Read character from Serial Port */ { while (!(U1LSR & 0x01)); return (U1RBR); }
×
×
  • Создать...