#include "disk.h"\r
#include "led.h"\r
#include "time.h"\r
+#include "trace.h"\r
\r
const char* Notice = "Copyright (C) 2014 Michael McMaster <michael@codesrc.com>";\r
\r
{\r
timeInit();\r
ledInit();\r
+ traceInit();\r
\r
// Enable global interrupts.\r
// Needed for RST and ATN interrupt handlers.\r
#include "scsi.h"\r
#include "scsiPhy.h"\r
#include "bits.h"\r
+#include "trace.h"\r
\r
#define scsiTarget_AUX_CTL (* (reg8 *) scsiTarget_datapath__DP_AUX_CTL_REG)\r
\r
CY_ISR_PROTO(scsiRxCompleteISR);\r
CY_ISR(scsiRxCompleteISR)\r
{\r
+ traceIrq(trace_scsiRxCompleteISR);\r
scsiRxDMAComplete = 1;\r
}\r
\r
CY_ISR_PROTO(scsiTxCompleteISR);\r
CY_ISR(scsiTxCompleteISR)\r
{\r
+ traceIrq(trace_scsiTxCompleteISR);\r
scsiTxDMAComplete = 1;\r
}\r
\r
CY_ISR_PROTO(scsiResetISR);\r
CY_ISR(scsiResetISR)\r
{\r
+ traceIrq(trace_scsiResetISR);\r
scsiDev.resetFlag = 1;\r
}\r
\r
uint8_t\r
scsiReadByte(void)\r
{\r
+ trace(trace_spinPhyTxFifo);\r
while (unlikely(scsiPhyTxFifoFull()) && likely(!scsiDev.resetFlag)) {}\r
scsiPhyTx(0);\r
\r
+ trace(trace_spinPhyRxFifo);\r
while (scsiPhyRxFifoEmpty() && likely(!scsiDev.resetFlag)) {}\r
uint8_t val = scsiPhyRx();\r
scsiDev.parityError = scsiDev.parityError || SCSI_Parity_Error_Read();\r
\r
+ trace(trace_spinTxComplete);\r
while (!(scsiPhyStatus() & SCSI_PHY_TX_COMPLETE) && likely(!scsiDev.resetFlag)) {}\r
\r
return val;\r
{\r
// Prepare DMA transfer\r
dmaInProgress = 1;\r
+ trace(trace_doRxSingleDMA);\r
\r
CyDmaTdSetConfiguration(\r
scsiDmaTxTd[0],\r
{\r
// Wait until our scsi signals are consistent. This should only be\r
// a few cycles.\r
+ trace(trace_spinTxComplete);\r
while (!(scsiPhyStatus() & SCSI_PHY_TX_COMPLETE)) {}\r
\r
if (likely(dmaSentCount == dmaTotalCount))\r
else\r
{\r
scsiReadDMA(data, count);\r
- \r
+\r
// Wait for the next DMA interrupt (or the 1ms systick)\r
// It's beneficial to halt the processor to\r
// give the DMA controller more memory bandwidth to work with.\r
__WFI();\r
- \r
+\r
+ trace(trace_spinReadDMAPoll);\r
while (!scsiReadDMAPoll() && likely(!scsiDev.resetFlag)) {};\r
}\r
}\r
void\r
scsiWriteByte(uint8 value)\r
{\r
+ trace(trace_spinPhyTxFifo);\r
while (unlikely(scsiPhyTxFifoFull()) && likely(!scsiDev.resetFlag)) {}\r
scsiPhyTx(value);\r
\r
+ trace(trace_spinTxComplete);\r
while (!(scsiPhyStatus() & SCSI_PHY_TX_COMPLETE) && likely(!scsiDev.resetFlag)) {}\r
scsiPhyRxFifoClear();\r
}\r
}\r
}\r
\r
+ trace(trace_spinTxComplete);\r
while (!(scsiPhyStatus() & SCSI_PHY_TX_COMPLETE) && likely(!scsiDev.resetFlag)) {}\r
scsiPhyRxFifoClear();\r
}\r
{\r
// Prepare DMA transfer\r
dmaInProgress = 1;\r
+ trace(trace_doTxSingleDMA);\r
\r
CyDmaTdSetConfiguration(\r
scsiDmaTxTd[0],\r
{\r
// Wait until our scsi signals are consistent. This should only be\r
// a few cycles.\r
+ trace(trace_spinTxComplete);\r
while (!(scsiPhyStatus() & SCSI_PHY_TX_COMPLETE)) {}\r
\r
if (likely(dmaSentCount == dmaTotalCount))\r
else\r
{\r
scsiWriteDMA(data, count);\r
- \r
+\r
// Wait for the next DMA interrupt (or the 1ms systick)\r
// It's beneficial to halt the processor to\r
// give the DMA controller more memory bandwidth to work with.\r
__WFI();\r
\r
+ trace(trace_spinWriteDMAPoll);\r
while (!scsiWriteDMAPoll() && likely(!scsiDev.resetFlag)) {};\r
}\r
}\r
\r
void scsiPhyReset()\r
{\r
+ trace(trace_scsiPhyReset);\r
if (dmaInProgress)\r
{\r
dmaInProgress = 0;\r
dmaTotalCount = 0;\r
CyDmaChSetRequest(scsiDmaTxChan, CY_DMA_CPU_TERM_CHAIN);\r
CyDmaChSetRequest(scsiDmaRxChan, CY_DMA_CPU_TERM_CHAIN);\r
+ trace(trace_spinDMAReset);\r
while (!(scsiTxDMAComplete && scsiRxDMAComplete)) {}\r
\r
CyDmaChDisable(scsiDmaTxChan);\r
#include "sd.h"\r
#include "led.h"\r
#include "time.h"\r
+#include "trace.h"\r
\r
#include "scsiPhy.h"\r
\r
static uint8_t sdSpiByte(uint8_t value)\r
{\r
SDCard_WriteTxData(value);\r
+ trace(trace_spinSpiByte);\r
while (!(SDCard_ReadRxStatus() & SDCard_STS_RX_FIFO_NOT_EMPTY)) {}\r
+ trace(trace_sdSpiByte);\r
return SDCard_ReadRxData();\r
}\r
\r
// reads.\r
if (waitWhileBusy)\r
{\r
+ trace(trace_spinSDRxFIFO);\r
while (!(SDCard_ReadRxStatus() & SDCard_STS_RX_FIFO_NOT_EMPTY)) {}\r
int busy = SDCard_ReadRxData() != 0xFF;\r
if (unlikely(busy))\r
{\r
+ trace(trace_spinSDBusy);\r
while (sdSpiByte(0xFF) != 0xFF) {}\r
}\r
}\r
CyDmaChEnable(sdDMARxChan, 1);\r
CyDmaChEnable(sdDMATxChan, 1);\r
\r
+ trace(trace_spinSDDMA);\r
while (!(sdTxDMAComplete && sdRxDMAComplete)) { __WFI(); }\r
\r
uint16_t response = discardBuffer;\r
}\r
\r
uint32_t start = getTime_ms();\r
+\r
+ trace(trace_spinSDBusy);\r
while ((response & 0x80) && likely(elapsedTime_ms(start) <= 200))\r
{\r
response = sdSpiByte(0xFF);\r
// Don't wait more than 200ms. The standard recommends 100ms.\r
uint32_t start = getTime_ms();\r
uint8_t token = sdSpiByte(0xFF);\r
+ trace(trace_spinSDBusy);\r
while (token != 0xFE && likely(elapsedTime_ms(start) <= 200))\r
{\r
if (unlikely(token && ((token & 0xE0) == 0)))\r
// Not much choice but to wait until we've completed the transfer.\r
// Cancelling the transfer can't be done as we have no way to reset\r
// the SD card.\r
+ trace(trace_spinSDCompleteRead);\r
while (!sdReadSectorDMAPoll()) { /* spin */ }\r
}\r
\r
// Not much choice but to wait until we've completed the transfer.\r
// Cancelling the transfer can't be done as we have no way to reset\r
// the SD card.\r
+ trace(trace_spinSDCompleteWrite);\r
while (!sdWriteSectorDMAPoll(1)) { /* spin */ }\r
}\r
\r
--- /dev/null
+# Author James Laird-Wah <james@laird-wah.net>
+# This is free and unencumbered software released into the public domain.
+#
+# Anyone is free to copy, modify, publish, use, compile, sell, or
+# distribute this software, either in source code form or as a compiled
+# binary, for any purpose, commercial or non-commercial, and by any
+# means.
+#
+# In jurisdictions that recognize copyright laws, the author or authors
+# of this software dedicate any and all copyright interest in the
+# software to the public domain. We make this dedication for the benefit
+# of the public at large and to the detriment of our heirs and
+# successors. We intend this dedication to be an overt act of
+# relinquishment in perpetuity of all present and future rights to this
+# software under copyright law.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+
+# For more information, please refer to <http://unlicense.org/>
+open HDR, '<trace.h';
+$next = 0;
+$enum = 0;
+for (<HDR>) {
+ chomp;
+ /^enum trace_event/ || $enum or next;
+ $enum++;
+ /}/ && break;
+ /trace_(\S+)(\s*=\s*(\S+))?\s*,\s*$/ or next;
+ ($name, $valmatch, $val) = ($1, $2, $3);
+ $next = hex $val if defined $val;
+ $names{$next} = $name;
+ $next++;
+}
+
+while (!eof STDIN) {
+ $ch = ord getc;
+ if ($ch==1 || $ch==9) {
+ $data = ord getc;
+ print "ISR: " if $ch==9;
+ $name = $names{$data} // sprintf "unk: 0x%X", $data;
+ print $names{$data}, "\n"
+ } else {
+ print "<dropped>\n";
+ }
+}